aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/sme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-05-08 15:45:15 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-05-24 18:02:15 -0400
commit5fe231e873729fa2f57cdc417d5c1f80871e2d7d (patch)
tree48810991fa4cf4faa69c0a992fdaf962feb6edda /net/wireless/sme.c
parent73810b77def898b43a97638478692922b7f820eb (diff)
cfg80211: vastly simplify locking
Virtually all code paths in cfg80211 already (need to) hold the RTNL. As such, there's little point in having another four mutexes for various parts of the code, they just cause lock ordering issues (and much of the time, the RTNL and a few of the others need thus be held.) Simplify all this by getting rid of the extra four mutexes and just use the RTNL throughout. Only a few code changes were needed to do this and we can get rid of a work struct for bonus points. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/sme.c')
-rw-r--r--net/wireless/sme.c26
1 files changed, 4 insertions, 22 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 3ed35c345cae..4dbf31407a56 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -43,35 +43,29 @@ static bool cfg80211_is_all_idle(void)
43 struct wireless_dev *wdev; 43 struct wireless_dev *wdev;
44 bool is_all_idle = true; 44 bool is_all_idle = true;
45 45
46 mutex_lock(&cfg80211_mutex);
47
48 /* 46 /*
49 * All devices must be idle as otherwise if you are actively 47 * All devices must be idle as otherwise if you are actively
50 * scanning some new beacon hints could be learned and would 48 * scanning some new beacon hints could be learned and would
51 * count as new regulatory hints. 49 * count as new regulatory hints.
52 */ 50 */
53 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 51 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
54 cfg80211_lock_rdev(rdev);
55 list_for_each_entry(wdev, &rdev->wdev_list, list) { 52 list_for_each_entry(wdev, &rdev->wdev_list, list) {
56 wdev_lock(wdev); 53 wdev_lock(wdev);
57 if (wdev->sme_state != CFG80211_SME_IDLE) 54 if (wdev->sme_state != CFG80211_SME_IDLE)
58 is_all_idle = false; 55 is_all_idle = false;
59 wdev_unlock(wdev); 56 wdev_unlock(wdev);
60 } 57 }
61 cfg80211_unlock_rdev(rdev);
62 } 58 }
63 59
64 mutex_unlock(&cfg80211_mutex);
65
66 return is_all_idle; 60 return is_all_idle;
67} 61}
68 62
69static void disconnect_work(struct work_struct *work) 63static void disconnect_work(struct work_struct *work)
70{ 64{
71 if (!cfg80211_is_all_idle()) 65 rtnl_lock();
72 return; 66 if (cfg80211_is_all_idle())
73 67 regulatory_hint_disconnect();
74 regulatory_hint_disconnect(); 68 rtnl_unlock();
75} 69}
76 70
77static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); 71static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
@@ -85,7 +79,6 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
85 ASSERT_RTNL(); 79 ASSERT_RTNL();
86 ASSERT_RDEV_LOCK(rdev); 80 ASSERT_RDEV_LOCK(rdev);
87 ASSERT_WDEV_LOCK(wdev); 81 ASSERT_WDEV_LOCK(wdev);
88 lockdep_assert_held(&rdev->sched_scan_mtx);
89 82
90 if (rdev->scan_req) 83 if (rdev->scan_req)
91 return -EBUSY; 84 return -EBUSY;
@@ -226,9 +219,6 @@ void cfg80211_conn_work(struct work_struct *work)
226 u8 bssid_buf[ETH_ALEN], *bssid = NULL; 219 u8 bssid_buf[ETH_ALEN], *bssid = NULL;
227 220
228 rtnl_lock(); 221 rtnl_lock();
229 cfg80211_lock_rdev(rdev);
230 mutex_lock(&rdev->devlist_mtx);
231 mutex_lock(&rdev->sched_scan_mtx);
232 222
233 list_for_each_entry(wdev, &rdev->wdev_list, list) { 223 list_for_each_entry(wdev, &rdev->wdev_list, list) {
234 if (!wdev->netdev) 224 if (!wdev->netdev)
@@ -256,9 +246,6 @@ void cfg80211_conn_work(struct work_struct *work)
256 wdev_unlock(wdev); 246 wdev_unlock(wdev);
257 } 247 }
258 248
259 mutex_unlock(&rdev->sched_scan_mtx);
260 mutex_unlock(&rdev->devlist_mtx);
261 cfg80211_unlock_rdev(rdev);
262 rtnl_unlock(); 249 rtnl_unlock();
263} 250}
264 251
@@ -931,14 +918,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
931{ 918{
932 int err; 919 int err;
933 920
934 mutex_lock(&rdev->devlist_mtx);
935 /* might request scan - scan_mtx -> wdev_mtx dependency */
936 mutex_lock(&rdev->sched_scan_mtx);
937 wdev_lock(dev->ieee80211_ptr); 921 wdev_lock(dev->ieee80211_ptr);
938 err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL); 922 err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL);
939 wdev_unlock(dev->ieee80211_ptr); 923 wdev_unlock(dev->ieee80211_ptr);
940 mutex_unlock(&rdev->sched_scan_mtx);
941 mutex_unlock(&rdev->devlist_mtx);
942 924
943 return err; 925 return err;
944} 926}