summaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2017-04-26 09:58:53 +0200
committerJohannes Berg <johannes.berg@intel.com>2017-04-26 23:17:44 +0200
commit4a199068230bd8074f2e39025a2216390ea5b829 (patch)
tree88af85b1f1511f285731bb5fa6c863f60fd382fb /net/mac80211/util.c
parentmac80211: don't parse encrypted management frames in ieee80211_frame_acked (diff)
downloadlinux-4a199068230bd8074f2e39025a2216390ea5b829.tar.xz
linux-4a199068230bd8074f2e39025a2216390ea5b829.zip
mac80211: disentangle iflist_mtx and chanctx_mtx
At least on iwlwifi, sometimes lockdep complains that we can lock chanctx_mtx -> mvm.mutex -> iflist_mtx (due to iterate_interfaces) and iflist_mtx -> chanctx_mtx Remove the latter dependency in mac80211 by using the RTNL that we already hold in one case, and can relatively easily achieve in the other case. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7a37ce78bb38..37dad3dd6bac 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2791,8 +2791,10 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
struct ieee80211_sub_if_data *sdata;
struct cfg80211_chan_def chandef;
+ /* for interface list, to avoid linking iflist_mtx and chanctx_mtx */
+ ASSERT_RTNL();
+
mutex_lock(&local->mtx);
- mutex_lock(&local->iflist_mtx);
list_for_each_entry(sdata, &local->interfaces, list) {
/* it might be waiting for the local->mtx, but then
* by the time it gets it, sdata->wdev.cac_started
@@ -2809,7 +2811,6 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
GFP_KERNEL);
}
}
- mutex_unlock(&local->iflist_mtx);
mutex_unlock(&local->mtx);
}
@@ -2831,7 +2832,9 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
}
mutex_unlock(&local->chanctx_mtx);
+ rtnl_lock();
ieee80211_dfs_cac_cancel(local);
+ rtnl_unlock();
if (num_chanctx > 1)
/* XXX: multi-channel is not supported yet */
@@ -2846,7 +2849,7 @@ void ieee80211_radar_detected(struct ieee80211_hw *hw)
trace_api_radar_detected(local);
- ieee80211_queue_work(hw, &local->radar_detected_work);
+ schedule_work(&local->radar_detected_work);
}
EXPORT_SYMBOL(ieee80211_radar_detected);