summaryrefslogtreecommitdiffstats
path: root/net/wireless/scan.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/scan.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/scan.c')
-rw-r--r--net/wireless/scan.c42
1 files changed, 17 insertions, 25 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 2ce44a712f13..dd01b58fa78c 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -169,7 +169,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
169 union iwreq_data wrqu; 169 union iwreq_data wrqu;
170#endif 170#endif
171 171
172 lockdep_assert_held(&rdev->sched_scan_mtx); 172 ASSERT_RTNL();
173 173
174 request = rdev->scan_req; 174 request = rdev->scan_req;
175 175
@@ -230,9 +230,9 @@ void __cfg80211_scan_done(struct work_struct *wk)
230 rdev = container_of(wk, struct cfg80211_registered_device, 230 rdev = container_of(wk, struct cfg80211_registered_device,
231 scan_done_wk); 231 scan_done_wk);
232 232
233 mutex_lock(&rdev->sched_scan_mtx); 233 rtnl_lock();
234 ___cfg80211_scan_done(rdev, false); 234 ___cfg80211_scan_done(rdev, false);
235 mutex_unlock(&rdev->sched_scan_mtx); 235 rtnl_unlock();
236} 236}
237 237
238void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) 238void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
@@ -241,6 +241,7 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
241 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 241 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
242 242
243 request->aborted = aborted; 243 request->aborted = aborted;
244 request->notified = true;
244 queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk); 245 queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk);
245} 246}
246EXPORT_SYMBOL(cfg80211_scan_done); 247EXPORT_SYMBOL(cfg80211_scan_done);
@@ -255,7 +256,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
255 256
256 request = rdev->sched_scan_req; 257 request = rdev->sched_scan_req;
257 258
258 mutex_lock(&rdev->sched_scan_mtx); 259 rtnl_lock();
259 260
260 /* we don't have sched_scan_req anymore if the scan is stopping */ 261 /* we don't have sched_scan_req anymore if the scan is stopping */
261 if (request) { 262 if (request) {
@@ -270,7 +271,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
270 nl80211_send_sched_scan_results(rdev, request->dev); 271 nl80211_send_sched_scan_results(rdev, request->dev);
271 } 272 }
272 273
273 mutex_unlock(&rdev->sched_scan_mtx); 274 rtnl_unlock();
274} 275}
275 276
276void cfg80211_sched_scan_results(struct wiphy *wiphy) 277void cfg80211_sched_scan_results(struct wiphy *wiphy)
@@ -289,9 +290,9 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
289 290
290 trace_cfg80211_sched_scan_stopped(wiphy); 291 trace_cfg80211_sched_scan_stopped(wiphy);
291 292
292 mutex_lock(&rdev->sched_scan_mtx); 293 rtnl_lock();
293 __cfg80211_stop_sched_scan(rdev, true); 294 __cfg80211_stop_sched_scan(rdev, true);
294 mutex_unlock(&rdev->sched_scan_mtx); 295 rtnl_unlock();
295} 296}
296EXPORT_SYMBOL(cfg80211_sched_scan_stopped); 297EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
297 298
@@ -300,7 +301,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
300{ 301{
301 struct net_device *dev; 302 struct net_device *dev;
302 303
303 lockdep_assert_held(&rdev->sched_scan_mtx); 304 ASSERT_RTNL();
304 305
305 if (!rdev->sched_scan_req) 306 if (!rdev->sched_scan_req)
306 return -ENOENT; 307 return -ENOENT;
@@ -1043,21 +1044,19 @@ EXPORT_SYMBOL(cfg80211_unlink_bss);
1043static struct cfg80211_registered_device * 1044static struct cfg80211_registered_device *
1044cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) 1045cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
1045{ 1046{
1046 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV); 1047 struct cfg80211_registered_device *rdev;
1047 struct net_device *dev; 1048 struct net_device *dev;
1048 1049
1049 mutex_lock(&cfg80211_mutex); 1050 ASSERT_RTNL();
1051
1050 dev = dev_get_by_index(net, ifindex); 1052 dev = dev_get_by_index(net, ifindex);
1051 if (!dev) 1053 if (!dev)
1052 goto out; 1054 return ERR_PTR(-ENODEV);
1053 if (dev->ieee80211_ptr) { 1055 if (dev->ieee80211_ptr)
1054 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy); 1056 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
1055 mutex_lock(&rdev->mtx); 1057 else
1056 } else
1057 rdev = ERR_PTR(-ENODEV); 1058 rdev = ERR_PTR(-ENODEV);
1058 dev_put(dev); 1059 dev_put(dev);
1059 out:
1060 mutex_unlock(&cfg80211_mutex);
1061 return rdev; 1060 return rdev;
1062} 1061}
1063 1062
@@ -1083,7 +1082,6 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1083 if (IS_ERR(rdev)) 1082 if (IS_ERR(rdev))
1084 return PTR_ERR(rdev); 1083 return PTR_ERR(rdev);
1085 1084
1086 mutex_lock(&rdev->sched_scan_mtx);
1087 if (rdev->scan_req) { 1085 if (rdev->scan_req) {
1088 err = -EBUSY; 1086 err = -EBUSY;
1089 goto out; 1087 goto out;
@@ -1190,9 +1188,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1190 dev_hold(dev); 1188 dev_hold(dev);
1191 } 1189 }
1192 out: 1190 out:
1193 mutex_unlock(&rdev->sched_scan_mtx);
1194 kfree(creq); 1191 kfree(creq);
1195 cfg80211_unlock_rdev(rdev);
1196 return err; 1192 return err;
1197} 1193}
1198EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); 1194EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
@@ -1491,10 +1487,8 @@ int cfg80211_wext_giwscan(struct net_device *dev,
1491 if (IS_ERR(rdev)) 1487 if (IS_ERR(rdev))
1492 return PTR_ERR(rdev); 1488 return PTR_ERR(rdev);
1493 1489
1494 if (rdev->scan_req) { 1490 if (rdev->scan_req)
1495 res = -EAGAIN; 1491 return -EAGAIN;
1496 goto out;
1497 }
1498 1492
1499 res = ieee80211_scan_results(rdev, info, extra, data->length); 1493 res = ieee80211_scan_results(rdev, info, extra, data->length);
1500 data->length = 0; 1494 data->length = 0;
@@ -1503,8 +1497,6 @@ int cfg80211_wext_giwscan(struct net_device *dev,
1503 res = 0; 1497 res = 0;
1504 } 1498 }
1505 1499
1506 out:
1507 cfg80211_unlock_rdev(rdev);
1508 return res; 1500 return res;
1509} 1501}
1510EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan); 1502EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);