diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-05-08 15:45:15 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-05-24 18:02:15 -0400 |
commit | 5fe231e873729fa2f57cdc417d5c1f80871e2d7d (patch) | |
tree | 48810991fa4cf4faa69c0a992fdaf962feb6edda /net/wireless/core.h | |
parent | 73810b77def898b43a97638478692922b7f820eb (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.h | 32 |
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 @@ | |||
23 | struct cfg80211_registered_device { | 22 | struct 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 | ||
122 | extern struct workqueue_struct *cfg80211_wq; | 112 | extern struct workqueue_struct *cfg80211_wq; |
123 | extern struct mutex cfg80211_mutex; | ||
124 | extern struct list_head cfg80211_rdev_list; | 113 | extern struct list_head cfg80211_rdev_list; |
125 | extern int cfg80211_rdev_list_generation; | 114 | extern int cfg80211_rdev_list_generation; |
126 | 115 | ||
127 | static inline void assert_cfg80211_lock(void) | ||
128 | { | ||
129 | lockdep_assert_held(&cfg80211_mutex); | ||
130 | } | ||
131 | |||
132 | struct cfg80211_internal_bss { | 116 | struct 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) | |||
161 | struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); | 145 | struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); |
162 | int get_wiphy_idx(struct wiphy *wiphy); | 146 | int get_wiphy_idx(struct wiphy *wiphy); |
163 | 147 | ||
164 | /* requires cfg80211_rdev_mutex to be held! */ | ||
165 | struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); | 148 | struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); |
166 | 149 | ||
167 | int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, | 150 | int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, |
168 | struct net *net); | 151 | struct net *net); |
169 | 152 | ||
170 | static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev) | ||
171 | { | ||
172 | mutex_lock(&rdev->mtx); | ||
173 | } | ||
174 | |||
175 | static 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 | |||
181 | static inline void wdev_lock(struct wireless_dev *wdev) | 153 | static 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 | ||
198 | static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) | 170 | static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) |