mirror of https://gitee.com/openkylin/linux.git
qtnfmac: do not use mutexes in timer context
The function qtnf_scan_done makes use of mutexes which is wrong since it may be called from timer context. Move scan timeout handler from timer to deferred work. Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
39845020b3
commit
f2cddd5469
|
@ -595,19 +595,13 @@ qtnf_del_station(struct wiphy *wiphy, struct net_device *dev,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qtnf_scan_timeout(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct qtnf_wmac *mac = from_timer(mac, t, scan_timeout);
|
|
||||||
|
|
||||||
pr_warn("mac%d scan timed out\n", mac->macid);
|
|
||||||
qtnf_scan_done(mac, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
|
qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
|
||||||
{
|
{
|
||||||
struct qtnf_wmac *mac = wiphy_priv(wiphy);
|
struct qtnf_wmac *mac = wiphy_priv(wiphy);
|
||||||
|
|
||||||
|
cancel_delayed_work_sync(&mac->scan_timeout);
|
||||||
|
|
||||||
mac->scan_req = request;
|
mac->scan_req = request;
|
||||||
|
|
||||||
if (qtnf_cmd_send_scan(mac)) {
|
if (qtnf_cmd_send_scan(mac)) {
|
||||||
|
@ -616,9 +610,8 @@ qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
mac->scan_timeout.function = qtnf_scan_timeout;
|
queue_delayed_work(mac->bus->workqueue, &mac->scan_timeout,
|
||||||
mod_timer(&mac->scan_timeout,
|
QTNF_SCAN_TIMEOUT_SEC * HZ);
|
||||||
jiffies + QTNF_SCAN_TIMEOUT_SEC * HZ);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,23 +28,4 @@ void qtnf_band_init_rates(struct ieee80211_supported_band *band);
|
||||||
void qtnf_band_setup_htvht_caps(struct qtnf_mac_info *macinfo,
|
void qtnf_band_setup_htvht_caps(struct qtnf_mac_info *macinfo,
|
||||||
struct ieee80211_supported_band *band);
|
struct ieee80211_supported_band *band);
|
||||||
|
|
||||||
static inline void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted)
|
|
||||||
{
|
|
||||||
struct cfg80211_scan_info info = {
|
|
||||||
.aborted = aborted,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (timer_pending(&mac->scan_timeout))
|
|
||||||
del_timer_sync(&mac->scan_timeout);
|
|
||||||
|
|
||||||
mutex_lock(&mac->mac_lock);
|
|
||||||
|
|
||||||
if (mac->scan_req) {
|
|
||||||
cfg80211_scan_done(mac->scan_req, &info);
|
|
||||||
mac->scan_req = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&mac->mac_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _QTN_FMAC_CFG80211_H_ */
|
#endif /* _QTN_FMAC_CFG80211_H_ */
|
||||||
|
|
|
@ -311,6 +311,37 @@ static void qtnf_mac_init_primary_intf(struct qtnf_wmac *mac)
|
||||||
vif->cons_tx_timeout_cnt = 0;
|
vif->cons_tx_timeout_cnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qtnf_mac_scan_finish(struct qtnf_wmac *mac, bool aborted)
|
||||||
|
{
|
||||||
|
struct cfg80211_scan_info info = {
|
||||||
|
.aborted = aborted,
|
||||||
|
};
|
||||||
|
|
||||||
|
mutex_lock(&mac->mac_lock);
|
||||||
|
|
||||||
|
if (mac->scan_req) {
|
||||||
|
cfg80211_scan_done(mac->scan_req, &info);
|
||||||
|
mac->scan_req = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&mac->mac_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted)
|
||||||
|
{
|
||||||
|
cancel_delayed_work_sync(&mac->scan_timeout);
|
||||||
|
qtnf_mac_scan_finish(mac, aborted);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qtnf_mac_scan_timeout(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct qtnf_wmac *mac =
|
||||||
|
container_of(work, struct qtnf_wmac, scan_timeout.work);
|
||||||
|
|
||||||
|
pr_warn("MAC%d: scan timed out\n", mac->macid);
|
||||||
|
qtnf_mac_scan_finish(mac, true);
|
||||||
|
}
|
||||||
|
|
||||||
static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
|
static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
|
||||||
unsigned int macid)
|
unsigned int macid)
|
||||||
{
|
{
|
||||||
|
@ -334,7 +365,7 @@ static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
|
||||||
mac->iflist[i].vifid = i;
|
mac->iflist[i].vifid = i;
|
||||||
qtnf_sta_list_init(&mac->iflist[i].sta_list);
|
qtnf_sta_list_init(&mac->iflist[i].sta_list);
|
||||||
mutex_init(&mac->mac_lock);
|
mutex_init(&mac->mac_lock);
|
||||||
timer_setup(&mac->scan_timeout, NULL, 0);
|
INIT_DELAYED_WORK(&mac->scan_timeout, qtnf_mac_scan_timeout);
|
||||||
mac->iflist[i].stats64 =
|
mac->iflist[i].stats64 =
|
||||||
netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
|
netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
|
||||||
if (!mac->iflist[i].stats64)
|
if (!mac->iflist[i].stats64)
|
||||||
|
|
|
@ -133,7 +133,7 @@ struct qtnf_wmac {
|
||||||
struct qtnf_vif iflist[QTNF_MAX_INTF];
|
struct qtnf_vif iflist[QTNF_MAX_INTF];
|
||||||
struct cfg80211_scan_request *scan_req;
|
struct cfg80211_scan_request *scan_req;
|
||||||
struct mutex mac_lock; /* lock during wmac speicific ops */
|
struct mutex mac_lock; /* lock during wmac speicific ops */
|
||||||
struct timer_list scan_timeout;
|
struct delayed_work scan_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qtnf_hw_info {
|
struct qtnf_hw_info {
|
||||||
|
@ -168,6 +168,7 @@ void qtnf_update_tx_stats(struct net_device *ndev, const struct sk_buff *skb);
|
||||||
void qtnf_virtual_intf_cleanup(struct net_device *ndev);
|
void qtnf_virtual_intf_cleanup(struct net_device *ndev);
|
||||||
|
|
||||||
void qtnf_netdev_updown(struct net_device *ndev, bool up);
|
void qtnf_netdev_updown(struct net_device *ndev, bool up);
|
||||||
|
void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted);
|
||||||
|
|
||||||
static inline struct qtnf_vif *qtnf_netdev_get_priv(struct net_device *dev)
|
static inline struct qtnf_vif *qtnf_netdev_get_priv(struct net_device *dev)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue