aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/core.h
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/core.h
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/core.h')
-rw-r--r--net/wireless/core.h32
1 files changed, 2 insertions, 30 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 95b29075a9c8..d21a0fc01401 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -5,7 +5,6 @@
5 */ 5 */
6#ifndef __NET_WIRELESS_CORE_H 6#ifndef __NET_WIRELESS_CORE_H
7#define __NET_WIRELESS_CORE_H 7#define __NET_WIRELESS_CORE_H
8#include <linux/mutex.h>
9#include <linux/list.h> 8#include <linux/list.h>
10#include <linux/netdevice.h> 9#include <linux/netdevice.h>
11#include <linux/rbtree.h> 10#include <linux/rbtree.h>
@@ -23,11 +22,6 @@
23struct cfg80211_registered_device { 22struct cfg80211_registered_device {
24 const struct cfg80211_ops *ops; 23 const struct cfg80211_ops *ops;
25 struct list_head list; 24 struct list_head list;
26 /* we hold this mutex during any call so that
27 * we cannot do multiple calls at once, and also
28 * to avoid the deregister call to proceed while
29 * any call is in progress */
30 struct mutex mtx;
31 25
32 /* rfkill support */ 26 /* rfkill support */
33 struct rfkill_ops rfkill_ops; 27 struct rfkill_ops rfkill_ops;
@@ -49,9 +43,7 @@ struct cfg80211_registered_device {
49 /* wiphy index, internal only */ 43 /* wiphy index, internal only */
50 int wiphy_idx; 44 int wiphy_idx;
51 45
52 /* associated wireless interfaces */ 46 /* associated wireless interfaces, protected by rtnl or RCU */
53 struct mutex devlist_mtx;
54 /* protected by devlist_mtx or RCU */
55 struct list_head wdev_list; 47 struct list_head wdev_list;
56 int devlist_generation, wdev_id; 48 int devlist_generation, wdev_id;
57 int opencount; /* also protected by devlist_mtx */ 49 int opencount; /* also protected by devlist_mtx */
@@ -75,8 +67,6 @@ struct cfg80211_registered_device {
75 struct work_struct scan_done_wk; 67 struct work_struct scan_done_wk;
76 struct work_struct sched_scan_results_wk; 68 struct work_struct sched_scan_results_wk;
77 69
78 struct mutex sched_scan_mtx;
79
80#ifdef CONFIG_NL80211_TESTMODE 70#ifdef CONFIG_NL80211_TESTMODE
81 struct genl_info *testmode_info; 71 struct genl_info *testmode_info;
82#endif 72#endif
@@ -120,15 +110,9 @@ cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
120} 110}
121 111
122extern struct workqueue_struct *cfg80211_wq; 112extern struct workqueue_struct *cfg80211_wq;
123extern struct mutex cfg80211_mutex;
124extern struct list_head cfg80211_rdev_list; 113extern struct list_head cfg80211_rdev_list;
125extern int cfg80211_rdev_list_generation; 114extern int cfg80211_rdev_list_generation;
126 115
127static inline void assert_cfg80211_lock(void)
128{
129 lockdep_assert_held(&cfg80211_mutex);
130}
131
132struct cfg80211_internal_bss { 116struct cfg80211_internal_bss {
133 struct list_head list; 117 struct list_head list;
134 struct list_head hidden_list; 118 struct list_head hidden_list;
@@ -161,23 +145,11 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
161struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); 145struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
162int get_wiphy_idx(struct wiphy *wiphy); 146int get_wiphy_idx(struct wiphy *wiphy);
163 147
164/* requires cfg80211_rdev_mutex to be held! */
165struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); 148struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
166 149
167int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, 150int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
168 struct net *net); 151 struct net *net);
169 152
170static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
171{
172 mutex_lock(&rdev->mtx);
173}
174
175static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *rdev)
176{
177 BUG_ON(IS_ERR(rdev) || !rdev);
178 mutex_unlock(&rdev->mtx);
179}
180
181static inline void wdev_lock(struct wireless_dev *wdev) 153static inline void wdev_lock(struct wireless_dev *wdev)
182 __acquires(wdev) 154 __acquires(wdev)
183{ 155{
@@ -192,7 +164,7 @@ static inline void wdev_unlock(struct wireless_dev *wdev)
192 mutex_unlock(&wdev->mtx); 164 mutex_unlock(&wdev->mtx);
193} 165}
194 166
195#define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx) 167#define ASSERT_RDEV_LOCK(rdev) ASSERT_RTNL()
196#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) 168#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
197 169
198static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) 170static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev)