Commit 38fd2143 authored by Johannes Berg's avatar Johannes Berg

regulatory: remove reg_mutex

The reg_mutex is similar to the ones I just removed in
cfg80211 but even less useful since it protects global
data, and we hold the RTNL in all places (except module
unload) already.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent db2424c5
...@@ -81,7 +81,10 @@ static struct regulatory_request core_request_world = { ...@@ -81,7 +81,10 @@ static struct regulatory_request core_request_world = {
.country_ie_env = ENVIRON_ANY, .country_ie_env = ENVIRON_ANY,
}; };
/* Receipt of information from last regulatory request */ /*
* Receipt of information from last regulatory request,
* protected by RTNL (and can be accessed with RCU protection)
*/
static struct regulatory_request __rcu *last_request = static struct regulatory_request __rcu *last_request =
(void __rcu *)&core_request_world; (void __rcu *)&core_request_world;
...@@ -96,39 +99,25 @@ static struct device_type reg_device_type = { ...@@ -96,39 +99,25 @@ static struct device_type reg_device_type = {
* Central wireless core regulatory domains, we only need two, * Central wireless core regulatory domains, we only need two,
* the current one and a world regulatory domain in case we have no * the current one and a world regulatory domain in case we have no
* information to give us an alpha2. * information to give us an alpha2.
* (protected by RTNL, can be read under RCU)
*/ */
const struct ieee80211_regdomain __rcu *cfg80211_regdomain; const struct ieee80211_regdomain __rcu *cfg80211_regdomain;
/*
* Protects static reg.c components:
* - cfg80211_regdomain (if not used with RCU)
* - cfg80211_world_regdom
* - last_request (if not used with RCU)
* - reg_num_devs_support_basehint
*/
static DEFINE_MUTEX(reg_mutex);
/* /*
* Number of devices that registered to the core * Number of devices that registered to the core
* that support cellular base station regulatory hints * that support cellular base station regulatory hints
* (protected by RTNL)
*/ */
static int reg_num_devs_support_basehint; static int reg_num_devs_support_basehint;
static inline void assert_reg_lock(void)
{
lockdep_assert_held(&reg_mutex);
}
static const struct ieee80211_regdomain *get_cfg80211_regdom(void) static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
{ {
return rcu_dereference_protected(cfg80211_regdomain, return rtnl_dereference(cfg80211_regdomain);
lockdep_is_held(&reg_mutex));
} }
static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy) static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
{ {
return rcu_dereference_protected(wiphy->regd, return rtnl_dereference(wiphy->regd);
lockdep_is_held(&reg_mutex));
} }
static void rcu_free_regdom(const struct ieee80211_regdomain *r) static void rcu_free_regdom(const struct ieee80211_regdomain *r)
...@@ -140,8 +129,7 @@ static void rcu_free_regdom(const struct ieee80211_regdomain *r) ...@@ -140,8 +129,7 @@ static void rcu_free_regdom(const struct ieee80211_regdomain *r)
static struct regulatory_request *get_last_request(void) static struct regulatory_request *get_last_request(void)
{ {
return rcu_dereference_check(last_request, return rcu_dereference_rtnl(last_request);
lockdep_is_held(&reg_mutex));
} }
/* Used to queue up regulatory hints */ /* Used to queue up regulatory hints */
...@@ -200,6 +188,7 @@ static const struct ieee80211_regdomain world_regdom = { ...@@ -200,6 +188,7 @@ static const struct ieee80211_regdomain world_regdom = {
} }
}; };
/* protected by RTNL */
static const struct ieee80211_regdomain *cfg80211_world_regdom = static const struct ieee80211_regdomain *cfg80211_world_regdom =
&world_regdom; &world_regdom;
...@@ -215,7 +204,7 @@ static void reset_regdomains(bool full_reset, ...@@ -215,7 +204,7 @@ static void reset_regdomains(bool full_reset,
const struct ieee80211_regdomain *r; const struct ieee80211_regdomain *r;
struct regulatory_request *lr; struct regulatory_request *lr;
assert_reg_lock(); ASSERT_RTNL();
r = get_cfg80211_regdom(); r = get_cfg80211_regdom();
...@@ -936,13 +925,7 @@ static bool reg_request_cell_base(struct regulatory_request *request) ...@@ -936,13 +925,7 @@ static bool reg_request_cell_base(struct regulatory_request *request)
bool reg_last_request_cell_base(void) bool reg_last_request_cell_base(void)
{ {
bool val; return reg_request_cell_base(get_last_request());
mutex_lock(&reg_mutex);
val = reg_request_cell_base(get_last_request());
mutex_unlock(&reg_mutex);
return val;
} }
#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS
...@@ -1444,8 +1427,6 @@ static void reg_set_request_processed(void) ...@@ -1444,8 +1427,6 @@ static void reg_set_request_processed(void)
* what it believes should be the current regulatory domain. * what it believes should be the current regulatory domain.
* *
* Returns one of the different reg request treatment values. * Returns one of the different reg request treatment values.
*
* Caller must hold &reg_mutex
*/ */
static enum reg_request_treatment static enum reg_request_treatment
__regulatory_hint(struct wiphy *wiphy, __regulatory_hint(struct wiphy *wiphy,
...@@ -1622,10 +1603,8 @@ static void reg_process_pending_beacon_hints(void) ...@@ -1622,10 +1603,8 @@ static void reg_process_pending_beacon_hints(void)
static void reg_todo(struct work_struct *work) static void reg_todo(struct work_struct *work)
{ {
rtnl_lock(); rtnl_lock();
mutex_lock(&reg_mutex);
reg_process_pending_hints(); reg_process_pending_hints();
reg_process_pending_beacon_hints(); reg_process_pending_beacon_hints();
mutex_unlock(&reg_mutex);
rtnl_unlock(); rtnl_unlock();
} }
...@@ -1851,8 +1830,6 @@ static void restore_regulatory_settings(bool reset_user) ...@@ -1851,8 +1830,6 @@ static void restore_regulatory_settings(bool reset_user)
ASSERT_RTNL(); ASSERT_RTNL();
mutex_lock(&reg_mutex);
reset_regdomains(true, &world_regdom); reset_regdomains(true, &world_regdom);
restore_alpha2(alpha2, reset_user); restore_alpha2(alpha2, reset_user);
...@@ -1906,8 +1883,6 @@ static void restore_regulatory_settings(bool reset_user) ...@@ -1906,8 +1883,6 @@ static void restore_regulatory_settings(bool reset_user)
list_splice_tail_init(&tmp_reg_req_list, &reg_requests_list); list_splice_tail_init(&tmp_reg_req_list, &reg_requests_list);
spin_unlock(&reg_requests_lock); spin_unlock(&reg_requests_lock);
mutex_unlock(&reg_mutex);
REG_DBG_PRINT("Kicking the queue\n"); REG_DBG_PRINT("Kicking the queue\n");
schedule_work(&reg_work); schedule_work(&reg_work);
...@@ -2222,7 +2197,6 @@ int set_regdom(const struct ieee80211_regdomain *rd) ...@@ -2222,7 +2197,6 @@ int set_regdom(const struct ieee80211_regdomain *rd)
struct regulatory_request *lr; struct regulatory_request *lr;
int r; int r;
mutex_lock(&reg_mutex);
lr = get_last_request(); lr = get_last_request();
/* Note that this doesn't update the wiphys, this is done below */ /* Note that this doesn't update the wiphys, this is done below */
...@@ -2232,14 +2206,12 @@ int set_regdom(const struct ieee80211_regdomain *rd) ...@@ -2232,14 +2206,12 @@ int set_regdom(const struct ieee80211_regdomain *rd)
reg_set_request_processed(); reg_set_request_processed();
kfree(rd); kfree(rd);
goto out; return r;
} }
/* This would make this whole thing pointless */ /* This would make this whole thing pointless */
if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom())) { if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom()))
r = -EINVAL; return -EINVAL;
goto out;
}
/* update all wiphys now with the new established regulatory domain */ /* update all wiphys now with the new established regulatory domain */
update_all_wiphy_regulatory(lr->initiator); update_all_wiphy_regulatory(lr->initiator);
...@@ -2250,10 +2222,7 @@ int set_regdom(const struct ieee80211_regdomain *rd) ...@@ -2250,10 +2222,7 @@ int set_regdom(const struct ieee80211_regdomain *rd)
reg_set_request_processed(); reg_set_request_processed();
out: return 0;
mutex_unlock(&reg_mutex);
return r;
} }
int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
...@@ -2278,14 +2247,10 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -2278,14 +2247,10 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
void wiphy_regulatory_register(struct wiphy *wiphy) void wiphy_regulatory_register(struct wiphy *wiphy)
{ {
mutex_lock(&reg_mutex);
if (!reg_dev_ignore_cell_hint(wiphy)) if (!reg_dev_ignore_cell_hint(wiphy))
reg_num_devs_support_basehint++; reg_num_devs_support_basehint++;
wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
mutex_unlock(&reg_mutex);
} }
void wiphy_regulatory_deregister(struct wiphy *wiphy) void wiphy_regulatory_deregister(struct wiphy *wiphy)
...@@ -2293,7 +2258,6 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy) ...@@ -2293,7 +2258,6 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
struct wiphy *request_wiphy = NULL; struct wiphy *request_wiphy = NULL;
struct regulatory_request *lr; struct regulatory_request *lr;
mutex_lock(&reg_mutex);
lr = get_last_request(); lr = get_last_request();
if (!reg_dev_ignore_cell_hint(wiphy)) if (!reg_dev_ignore_cell_hint(wiphy))
...@@ -2306,12 +2270,10 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy) ...@@ -2306,12 +2270,10 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
if (!request_wiphy || request_wiphy != wiphy) if (!request_wiphy || request_wiphy != wiphy)
goto out; return;
lr->wiphy_idx = WIPHY_IDX_INVALID; lr->wiphy_idx = WIPHY_IDX_INVALID;
lr->country_ie_env = ENVIRON_ANY; lr->country_ie_env = ENVIRON_ANY;
out:
mutex_unlock(&reg_mutex);
} }
static void reg_timeout_work(struct work_struct *work) static void reg_timeout_work(struct work_struct *work)
...@@ -2375,9 +2337,9 @@ void regulatory_exit(void) ...@@ -2375,9 +2337,9 @@ void regulatory_exit(void)
cancel_delayed_work_sync(&reg_timeout); cancel_delayed_work_sync(&reg_timeout);
/* Lock to suppress warnings */ /* Lock to suppress warnings */
mutex_lock(&reg_mutex); rtnl_lock();
reset_regdomains(true, NULL); reset_regdomains(true, NULL);
mutex_unlock(&reg_mutex); rtnl_unlock();
dev_set_uevent_suppress(&reg_pdev->dev, true); dev_set_uevent_suppress(&reg_pdev->dev, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment