summaryrefslogtreecommitdiff
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-03-05 13:14:08 +0100
committerJohannes Berg <johannes.berg@intel.com>2014-04-09 10:55:49 +0200
commit4e141dad266908735967b0961c8d90187825e0bc (patch)
tree2fe457b25b558543257bb3c73d888e4f4bab8b5b /net/mac80211/cfg.c
parentb6a550156bc08a472c9d2515631649e229fcfcef (diff)
mac80211: protect AP VLAN list with local->mtx
It was impossible to change chanctx of master AP for AP VLANs because the copy function requires RTNL which can't be simply taken in mac80211 code due to possible deadlocks. This is required for future chanctx reservation that re-bind vifs to new chanctx. This requires safe AP VLAN iteration without RTNL. Now VLANs can be iterated while holding either RTNL or local->mtx because the list is modified while holding both of these locks. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 23d60110aebd..aa39381ca46d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -983,10 +983,11 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
mutex_lock(&local->mtx);
err = ieee80211_vif_use_channel(sdata, &params->chandef,
IEEE80211_CHANCTX_SHARED);
+ if (!err)
+ ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
mutex_unlock(&local->mtx);
if (err)
return err;
- ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
/*
* Apply control port protocol, this allows us to
@@ -1139,8 +1140,8 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
skb_queue_purge(&sdata->u.ap.ps.bc_buf);
- ieee80211_vif_copy_chanctx_to_vlans(sdata, true);
mutex_lock(&local->mtx);
+ ieee80211_vif_copy_chanctx_to_vlans(sdata, true);
ieee80211_vif_release_channel(sdata);
mutex_unlock(&local->mtx);