summaryrefslogtreecommitdiff
path: root/net/mac80211/key.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-06-17 13:54:54 +0200
committerDavid S. Miller <davem@davemloft.net>2015-06-21 10:06:07 -0700
commit51f458d9612177f69c2e2c437034ae15f93078e7 (patch)
tree0240333477ebcabe65d564acc6500ad730a4139e /net/mac80211/key.c
parent7b48f45797be7c4bdbb772de80efe6bdcd78e81d (diff)
mac80211: fix locking in update_vlan_tailroom_need_count()
Unfortunately, Michal's change to fix AP_VLAN crypto tailroom caused a locking issue that was reported by lockdep, but only in a few cases - the issue was a classic ABBA deadlock caused by taking the mtx after the key_mtx, where normally they're taken the other way around. As the key mutex protects the field in question (I'm adding a few annotations to make that clear) only the iteration needs to be protected, but we can also iterate the interface list with just RCU protection while holding the key mutex. Fixes: f9dca80b98ca ("mac80211: fix AP_VLAN crypto tailroom calculation") Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r--net/mac80211/key.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index a907f2d5c12d..81e9785f38bc 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -66,12 +66,15 @@ update_vlan_tailroom_need_count(struct ieee80211_sub_if_data *sdata, int delta)
if (sdata->vif.type != NL80211_IFTYPE_AP)
return;
- mutex_lock(&sdata->local->mtx);
+ /* crypto_tx_tailroom_needed_cnt is protected by this */
+ assert_key_lock(sdata->local);
+
+ rcu_read_lock();
- list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
+ list_for_each_entry_rcu(vlan, &sdata->u.ap.vlans, u.vlan.list)
vlan->crypto_tx_tailroom_needed_cnt += delta;
- mutex_unlock(&sdata->local->mtx);
+ rcu_read_unlock();
}
static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
@@ -95,6 +98,8 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
* http://mid.gmane.org/1308590980.4322.19.camel@jlt3.sipsolutions.net
*/
+ assert_key_lock(sdata->local);
+
update_vlan_tailroom_need_count(sdata, 1);
if (!sdata->crypto_tx_tailroom_needed_cnt++) {
@@ -109,6 +114,8 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
static void decrease_tailroom_need_count(struct ieee80211_sub_if_data *sdata,
int delta)
{
+ assert_key_lock(sdata->local);
+
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt < delta);
update_vlan_tailroom_need_count(sdata, -delta);