From 79010420cc3f78eab911598bfdd29c4b06a83e1f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 18 Sep 2007 17:29:21 -0400 Subject: [PATCH] mac80211: fix virtual interface locking Florian Lohoff noticed a bug in mac80211: when bringing the master interface down while other virtual interfaces are up we call dev_close() under a spinlock which is not allowed. This patch removes the sub_if_lock used by mac80211 in favour of using an RCU list. All list manipulations are already done under rtnl so are well protected against each other, and the read-side locks we took in the RX and TX code are already in RCU read-side critical sections. Signed-off-by: Johannes Berg Cc: Florian Lohoff Cc: Herbert Xu Cc: Michal Piotrowski Cc: Satyam Sharma Signed-off-by: Michael Wu Signed-off-by: John W. Linville --- net/mac80211/rx.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'net/mac80211/rx.c') diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 2535d8d4ce9..cb44a9db0e1 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1383,8 +1383,9 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, } /* - * key references are protected using RCU and this requires that - * we are in a read-site RCU section during receive processing + * key references and virtual interfaces are protected using RCU + * and this requires that we are in a read-side RCU section during + * receive processing */ rcu_read_lock(); @@ -1439,8 +1440,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, bssid = ieee80211_get_bssid(hdr, skb->len - radiotap_len); - read_lock(&local->sub_if_lock); - list_for_each_entry(sdata, &local->sub_if_list, list) { + list_for_each_entry_rcu(sdata, &local->interfaces, list) { rx.flags |= IEEE80211_TXRXD_RXRA_MATCH; if (!netif_running(sdata->dev)) @@ -1493,7 +1493,6 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, &rx, sta); } else dev_kfree_skb(skb); - read_unlock(&local->sub_if_lock); end: rcu_read_unlock(); -- cgit v1.2.3-70-g09d2