aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/reg.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-12-03 17:00:08 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-03 07:01:27 -0500
commite8da2bb4fe9ecb888f44714e2624c7d4268ac09d (patch)
treec776f0786e9d72c34888a25cec998f348ef64d70 /net/wireless/reg.c
parent5d885b999c68283c493cf00cc020260d38951ae6 (diff)
regulatory: clarify locking rules and assertions
Many places that currently check that cfg80211_mutex is held don't actually use any data protected by it. The functions that need to hold the cfg80211_mutex are the ones using the cfg80211_regdomain variable, so add the lock assertion to those and clarify this in the comments. The reason for this is that nl80211 uses the regdom without being able to hold reg_mutex. Acked-by: Luis R. Rodriguez <mcgrof@do-not-panic.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/reg.c')
-rw-r--r--net/wireless/reg.c31
1 files changed, 11 insertions, 20 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 75239789213a..603a01911a50 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -94,14 +94,14 @@ static struct device_type reg_device_type = {
94/* 94/*
95 * Central wireless core regulatory domains, we only need two, 95 * Central wireless core regulatory domains, we only need two,
96 * the current one and a world regulatory domain in case we have no 96 * the current one and a world regulatory domain in case we have no
97 * information to give us an alpha2 97 * information to give us an alpha2.
98 * Protected by the cfg80211_mutex.
98 */ 99 */
99const struct ieee80211_regdomain *cfg80211_regdomain; 100const struct ieee80211_regdomain *cfg80211_regdomain;
100 101
101/* 102/*
102 * Protects static reg.c components: 103 * Protects static reg.c components:
103 * - cfg80211_world_regdom 104 * - cfg80211_world_regdom
104 * - cfg80211_regdom
105 * - last_request 105 * - last_request
106 * - reg_num_devs_support_basehint 106 * - reg_num_devs_support_basehint
107 */ 107 */
@@ -185,6 +185,9 @@ MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
185 185
186static void reset_regdomains(bool full_reset) 186static void reset_regdomains(bool full_reset)
187{ 187{
188 assert_cfg80211_lock();
189 assert_reg_lock();
190
188 /* avoid freeing static information or freeing something twice */ 191 /* avoid freeing static information or freeing something twice */
189 if (cfg80211_regdomain == cfg80211_world_regdom) 192 if (cfg80211_regdomain == cfg80211_world_regdom)
190 cfg80211_regdomain = NULL; 193 cfg80211_regdomain = NULL;
@@ -215,6 +218,9 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd)
215{ 218{
216 WARN_ON(!last_request); 219 WARN_ON(!last_request);
217 220
221 assert_cfg80211_lock();
222 assert_reg_lock();
223
218 reset_regdomains(false); 224 reset_regdomains(false);
219 225
220 cfg80211_world_regdom = rd; 226 cfg80211_world_regdom = rd;
@@ -422,8 +428,6 @@ static int call_crda(const char *alpha2)
422/* Used by nl80211 before kmalloc'ing our regulatory domain */ 428/* Used by nl80211 before kmalloc'ing our regulatory domain */
423bool reg_is_valid_request(const char *alpha2) 429bool reg_is_valid_request(const char *alpha2)
424{ 430{
425 assert_cfg80211_lock();
426
427 if (!last_request) 431 if (!last_request)
428 return false; 432 return false;
429 433
@@ -915,8 +919,6 @@ bool reg_last_request_cell_base(void)
915{ 919{
916 bool val; 920 bool val;
917 921
918 assert_cfg80211_lock();
919
920 mutex_lock(&reg_mutex); 922 mutex_lock(&reg_mutex);
921 val = reg_request_cell_base(last_request); 923 val = reg_request_cell_base(last_request);
922 mutex_unlock(&reg_mutex); 924 mutex_unlock(&reg_mutex);
@@ -999,8 +1001,6 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx,
999 bool channel_changed = false; 1001 bool channel_changed = false;
1000 struct ieee80211_channel chan_before; 1002 struct ieee80211_channel chan_before;
1001 1003
1002 assert_cfg80211_lock();
1003
1004 sband = wiphy->bands[reg_beacon->chan.band]; 1004 sband = wiphy->bands[reg_beacon->chan.band];
1005 chan = &sband->channels[chan_idx]; 1005 chan = &sband->channels[chan_idx];
1006 1006
@@ -1042,8 +1042,6 @@ static void wiphy_update_new_beacon(struct wiphy *wiphy,
1042 unsigned int i; 1042 unsigned int i;
1043 struct ieee80211_supported_band *sband; 1043 struct ieee80211_supported_band *sband;
1044 1044
1045 assert_cfg80211_lock();
1046
1047 if (!wiphy->bands[reg_beacon->chan.band]) 1045 if (!wiphy->bands[reg_beacon->chan.band])
1048 return; 1046 return;
1049 1047
@@ -1062,8 +1060,6 @@ static void wiphy_update_beacon_reg(struct wiphy *wiphy)
1062 struct ieee80211_supported_band *sband; 1060 struct ieee80211_supported_band *sband;
1063 struct reg_beacon *reg_beacon; 1061 struct reg_beacon *reg_beacon;
1064 1062
1065 assert_cfg80211_lock();
1066
1067 list_for_each_entry(reg_beacon, &reg_beacon_list, list) { 1063 list_for_each_entry(reg_beacon, &reg_beacon_list, list) {
1068 if (!wiphy->bands[reg_beacon->chan.band]) 1064 if (!wiphy->bands[reg_beacon->chan.band])
1069 continue; 1065 continue;
@@ -1075,6 +1071,8 @@ static void wiphy_update_beacon_reg(struct wiphy *wiphy)
1075 1071
1076static bool reg_is_world_roaming(struct wiphy *wiphy) 1072static bool reg_is_world_roaming(struct wiphy *wiphy)
1077{ 1073{
1074 assert_cfg80211_lock();
1075
1078 if (is_world_regdom(cfg80211_regdomain->alpha2) || 1076 if (is_world_regdom(cfg80211_regdomain->alpha2) ||
1079 (wiphy->regd && is_world_regdom(wiphy->regd->alpha2))) 1077 (wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
1080 return true; 1078 return true;
@@ -1116,8 +1114,6 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
1116 struct ieee80211_channel *channel_before = NULL, *channel_after = NULL; 1114 struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
1117 unsigned int i; 1115 unsigned int i;
1118 1116
1119 assert_cfg80211_lock();
1120
1121 if (!is_ht40_allowed(channel)) { 1117 if (!is_ht40_allowed(channel)) {
1122 channel->flags |= IEEE80211_CHAN_NO_HT40; 1118 channel->flags |= IEEE80211_CHAN_NO_HT40;
1123 return; 1119 return;
@@ -1180,6 +1176,7 @@ static void wiphy_update_regulatory(struct wiphy *wiphy,
1180{ 1176{
1181 enum ieee80211_band band; 1177 enum ieee80211_band band;
1182 1178
1179 assert_cfg80211_lock();
1183 assert_reg_lock(); 1180 assert_reg_lock();
1184 1181
1185 if (ignore_reg_update(wiphy, initiator)) 1182 if (ignore_reg_update(wiphy, initiator))
@@ -1299,8 +1296,6 @@ get_reg_request_treatment(struct wiphy *wiphy,
1299{ 1296{
1300 struct wiphy *last_wiphy = NULL; 1297 struct wiphy *last_wiphy = NULL;
1301 1298
1302 assert_cfg80211_lock();
1303
1304 /* All initial requests are respected */ 1299 /* All initial requests are respected */
1305 if (!last_request) 1300 if (!last_request)
1306 return REG_REQ_OK; 1301 return REG_REQ_OK;
@@ -2246,8 +2241,6 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
2246 2241
2247void wiphy_regulatory_register(struct wiphy *wiphy) 2242void wiphy_regulatory_register(struct wiphy *wiphy)
2248{ 2243{
2249 assert_cfg80211_lock();
2250
2251 mutex_lock(&reg_mutex); 2244 mutex_lock(&reg_mutex);
2252 2245
2253 if (!reg_dev_ignore_cell_hint(wiphy)) 2246 if (!reg_dev_ignore_cell_hint(wiphy))
@@ -2263,8 +2256,6 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
2263{ 2256{
2264 struct wiphy *request_wiphy = NULL; 2257 struct wiphy *request_wiphy = NULL;
2265 2258
2266 assert_cfg80211_lock();
2267
2268 mutex_lock(&reg_mutex); 2259 mutex_lock(&reg_mutex);
2269 2260
2270 if (!reg_dev_ignore_cell_hint(wiphy)) 2261 if (!reg_dev_ignore_cell_hint(wiphy))