aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ibss.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-12-18 03:43:33 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-12-19 07:33:33 -0500
commit34a3740d6b392896b71e36cd5cd68837a8f94a5c (patch)
tree128f9a3e35af1e7fc768b55fc7173cac9e1a3b08 /net/mac80211/ibss.c
parent6924d0138acdf5026ee4463134d98e139fe025a2 (diff)
mac80211: fix iflist_mtx/mtx locking in radar detection
The scan code creates an iflist_mtx -> mtx locking dependency, and a few other places, notably radar detection, were creating the opposite dependency, causing lockdep to complain. As scan and radar detection are mutually exclusive, the deadlock can't really happen in practice, but it's still bad form. A similar issue exists in the monitor mode code, but this is only used by channel-context drivers right now and those have to have hardware scan, so that also can't happen. Still, fix these issues by making some of the channel context code require the mtx to be held rather than acquiring it, thus allowing the monitor/radar callers to keep the iflist_mtx->mtx lock ordering. While at it, also fix access to the local->scanning variable in the radar code, and document that radar_detect_enabled is now properly protected by the mtx. All this would now introduce an ABBA deadlock between the DFS work cancelling and local->mtx, so change the locking there a bit to not need to use cancel_delayed_work_sync() but be able to just use cancel_delayed_work(). The work is also safely stopped/removed when the interface is stopped, so no extra changes are needed. Reported-by: Kalle Valo <kvalo@qca.qualcomm.com> Tested-by: Simon Wunderlich <sw@simonwunderlich.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r--net/mac80211/ibss.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index d6ba841437b6..771080ec7212 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -293,14 +293,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
293 radar_required = true; 293 radar_required = true;
294 } 294 }
295 295
296 mutex_lock(&local->mtx);
296 ieee80211_vif_release_channel(sdata); 297 ieee80211_vif_release_channel(sdata);
297 if (ieee80211_vif_use_channel(sdata, &chandef, 298 if (ieee80211_vif_use_channel(sdata, &chandef,
298 ifibss->fixed_channel ? 299 ifibss->fixed_channel ?
299 IEEE80211_CHANCTX_SHARED : 300 IEEE80211_CHANCTX_SHARED :
300 IEEE80211_CHANCTX_EXCLUSIVE)) { 301 IEEE80211_CHANCTX_EXCLUSIVE)) {
301 sdata_info(sdata, "Failed to join IBSS, no channel context\n"); 302 sdata_info(sdata, "Failed to join IBSS, no channel context\n");
303 mutex_unlock(&local->mtx);
302 return; 304 return;
303 } 305 }
306 mutex_unlock(&local->mtx);
304 307
305 memcpy(ifibss->bssid, bssid, ETH_ALEN); 308 memcpy(ifibss->bssid, bssid, ETH_ALEN);
306 309
@@ -363,7 +366,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
363 sdata->vif.bss_conf.ssid_len = 0; 366 sdata->vif.bss_conf.ssid_len = 0;
364 RCU_INIT_POINTER(ifibss->presp, NULL); 367 RCU_INIT_POINTER(ifibss->presp, NULL);
365 kfree_rcu(presp, rcu_head); 368 kfree_rcu(presp, rcu_head);
369 mutex_lock(&local->mtx);
366 ieee80211_vif_release_channel(sdata); 370 ieee80211_vif_release_channel(sdata);
371 mutex_unlock(&local->mtx);
367 sdata_info(sdata, "Failed to join IBSS, driver failure: %d\n", 372 sdata_info(sdata, "Failed to join IBSS, driver failure: %d\n",
368 err); 373 err);
369 return; 374 return;
@@ -747,7 +752,9 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
747 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | 752 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
748 BSS_CHANGED_IBSS); 753 BSS_CHANGED_IBSS);
749 drv_leave_ibss(local, sdata); 754 drv_leave_ibss(local, sdata);
755 mutex_lock(&local->mtx);
750 ieee80211_vif_release_channel(sdata); 756 ieee80211_vif_release_channel(sdata);
757 mutex_unlock(&local->mtx);
751} 758}
752 759
753static void ieee80211_csa_connection_drop_work(struct work_struct *work) 760static void ieee80211_csa_connection_drop_work(struct work_struct *work)