Skip to content

Commit

Permalink
regulatory: clarify locking rules and assertions
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johannes Berg committed Jan 3, 2013
1 parent 5d885b9 commit e8da2bb
Showing 1 changed file with 11 additions and 20 deletions.
31 changes: 11 additions & 20 deletions net/wireless/reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ static struct device_type reg_device_type = {
/*
* Central wireless core regulatory domains, we only need two,
* 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 the cfg80211_mutex.
*/
const struct ieee80211_regdomain *cfg80211_regdomain;

/*
* Protects static reg.c components:
* - cfg80211_world_regdom
* - cfg80211_regdom
* - last_request
* - reg_num_devs_support_basehint
*/
Expand Down Expand Up @@ -185,6 +185,9 @@ MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");

static void reset_regdomains(bool full_reset)
{
assert_cfg80211_lock();
assert_reg_lock();

/* avoid freeing static information or freeing something twice */
if (cfg80211_regdomain == cfg80211_world_regdom)
cfg80211_regdomain = NULL;
Expand Down Expand Up @@ -215,6 +218,9 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd)
{
WARN_ON(!last_request);

assert_cfg80211_lock();
assert_reg_lock();

reset_regdomains(false);

cfg80211_world_regdom = rd;
Expand Down Expand Up @@ -422,8 +428,6 @@ static int call_crda(const char *alpha2)
/* Used by nl80211 before kmalloc'ing our regulatory domain */
bool reg_is_valid_request(const char *alpha2)
{
assert_cfg80211_lock();

if (!last_request)
return false;

Expand Down Expand Up @@ -915,8 +919,6 @@ bool reg_last_request_cell_base(void)
{
bool val;

assert_cfg80211_lock();

mutex_lock(&reg_mutex);
val = reg_request_cell_base(last_request);
mutex_unlock(&reg_mutex);
Expand Down Expand Up @@ -999,8 +1001,6 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx,
bool channel_changed = false;
struct ieee80211_channel chan_before;

assert_cfg80211_lock();

sband = wiphy->bands[reg_beacon->chan.band];
chan = &sband->channels[chan_idx];

Expand Down Expand Up @@ -1042,8 +1042,6 @@ static void wiphy_update_new_beacon(struct wiphy *wiphy,
unsigned int i;
struct ieee80211_supported_band *sband;

assert_cfg80211_lock();

if (!wiphy->bands[reg_beacon->chan.band])
return;

Expand All @@ -1062,8 +1060,6 @@ static void wiphy_update_beacon_reg(struct wiphy *wiphy)
struct ieee80211_supported_band *sband;
struct reg_beacon *reg_beacon;

assert_cfg80211_lock();

list_for_each_entry(reg_beacon, &reg_beacon_list, list) {
if (!wiphy->bands[reg_beacon->chan.band])
continue;
Expand All @@ -1075,6 +1071,8 @@ static void wiphy_update_beacon_reg(struct wiphy *wiphy)

static bool reg_is_world_roaming(struct wiphy *wiphy)
{
assert_cfg80211_lock();

if (is_world_regdom(cfg80211_regdomain->alpha2) ||
(wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
return true;
Expand Down Expand Up @@ -1116,8 +1114,6 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
unsigned int i;

assert_cfg80211_lock();

if (!is_ht40_allowed(channel)) {
channel->flags |= IEEE80211_CHAN_NO_HT40;
return;
Expand Down Expand Up @@ -1180,6 +1176,7 @@ static void wiphy_update_regulatory(struct wiphy *wiphy,
{
enum ieee80211_band band;

assert_cfg80211_lock();
assert_reg_lock();

if (ignore_reg_update(wiphy, initiator))
Expand Down Expand Up @@ -1299,8 +1296,6 @@ get_reg_request_treatment(struct wiphy *wiphy,
{
struct wiphy *last_wiphy = NULL;

assert_cfg80211_lock();

/* All initial requests are respected */
if (!last_request)
return REG_REQ_OK;
Expand Down Expand Up @@ -2246,8 +2241,6 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)

void wiphy_regulatory_register(struct wiphy *wiphy)
{
assert_cfg80211_lock();

mutex_lock(&reg_mutex);

if (!reg_dev_ignore_cell_hint(wiphy))
Expand All @@ -2263,8 +2256,6 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
{
struct wiphy *request_wiphy = NULL;

assert_cfg80211_lock();

mutex_lock(&reg_mutex);

if (!reg_dev_ignore_cell_hint(wiphy))
Expand Down

0 comments on commit e8da2bb

Please sign in to comment.