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>
This commit is contained in:
parent
cf147085fd
commit
4a19906823
|
@ -739,11 +739,8 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
|
|||
return 0;
|
||||
|
||||
mutex_lock(&local->mtx);
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
if (local->use_chanctx) {
|
||||
sdata = rcu_dereference_protected(
|
||||
local->monitor_sdata,
|
||||
lockdep_is_held(&local->iflist_mtx));
|
||||
sdata = rtnl_dereference(local->monitor_sdata);
|
||||
if (sdata) {
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
ret = ieee80211_vif_use_channel(sdata, chandef,
|
||||
|
@ -756,7 +753,6 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
|
|||
|
||||
if (ret == 0)
|
||||
local->monitor_chandef = *chandef;
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -253,6 +253,7 @@ static void ieee80211_restart_work(struct work_struct *work)
|
|||
WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
|
||||
"%s called with hardware scan in progress\n", __func__);
|
||||
|
||||
flush_work(&local->radar_detected_work);
|
||||
rtnl_lock();
|
||||
list_for_each_entry(sdata, &local->interfaces, list)
|
||||
flush_delayed_work(&sdata->dec_tailroom_needed_wk);
|
||||
|
@ -1187,6 +1188,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
|
|||
cancel_work_sync(&local->reconfig_filter);
|
||||
cancel_work_sync(&local->tdls_chsw_work);
|
||||
flush_work(&local->sched_scan_stopped_work);
|
||||
flush_work(&local->radar_detected_work);
|
||||
|
||||
ieee80211_clear_tx_pending(local);
|
||||
rate_control_deinitialize(local);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue