aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2013-02-04 12:44:44 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-11 12:44:55 -0500
commitf9e124fbd8cbea974b5dc7e9dafddd17d21df7e2 (patch)
treef09c89096de26a4211d73742933260d5d240b58e /net/mac80211/main.c
parent601513aa208f27ea87400a410d42c978421530ec (diff)
mac80211: protect rx-path with spinlock
This patch fixes the problem which was discussed in "mac80211: Fix PN corruption in case of multiple virtual interface" [1]. Amit Shakya reported a serious issue with my patch: mac80211: serialize rx path workers" [2]: In case, ieee80211_rx_handlers processing is going on for skbs received on one vif and at the same time, rx aggregation reorder timer expires on another vif then sta_rx_agg_reorder_timer_expired is invoked and it will push skbs into the single queue (local->rx_skb_queue). ieee80211_rx_handlers in the while loop assumes that the skbs are for the same sdata and sta. This assumption doesn't hold good in this scenario and the PN gets corrupted by PN received in other vif's skb, causing traffic to stop due to PN mismatch." [1] Message-Id: http://mid.gmane.org/201302041844.44436.chunkeey@googlemail.com [2] Commit-Id: 24a8fdad35835e8d71f7 Reported-by: Amit Shakya <amit.shakya@stericsson.com> Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c14
1 files changed, 1 insertions, 13 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 2bdd454e8bcf..2220331f4b7c 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -34,8 +34,6 @@
34#include "cfg.h" 34#include "cfg.h"
35#include "debugfs.h" 35#include "debugfs.h"
36 36
37static struct lock_class_key ieee80211_rx_skb_queue_class;
38
39void ieee80211_configure_filter(struct ieee80211_local *local) 37void ieee80211_configure_filter(struct ieee80211_local *local)
40{ 38{
41 u64 mc; 39 u64 mc;
@@ -613,21 +611,12 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
613 611
614 mutex_init(&local->key_mtx); 612 mutex_init(&local->key_mtx);
615 spin_lock_init(&local->filter_lock); 613 spin_lock_init(&local->filter_lock);
614 spin_lock_init(&local->rx_path_lock);
616 spin_lock_init(&local->queue_stop_reason_lock); 615 spin_lock_init(&local->queue_stop_reason_lock);
617 616
618 INIT_LIST_HEAD(&local->chanctx_list); 617 INIT_LIST_HEAD(&local->chanctx_list);
619 mutex_init(&local->chanctx_mtx); 618 mutex_init(&local->chanctx_mtx);
620 619
621 /*
622 * The rx_skb_queue is only accessed from tasklets,
623 * but other SKB queues are used from within IRQ
624 * context. Therefore, this one needs a different
625 * locking class so our direct, non-irq-safe use of
626 * the queue's lock doesn't throw lockdep warnings.
627 */
628 skb_queue_head_init_class(&local->rx_skb_queue,
629 &ieee80211_rx_skb_queue_class);
630
631 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); 620 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
632 621
633 INIT_WORK(&local->restart_work, ieee80211_restart_work); 622 INIT_WORK(&local->restart_work, ieee80211_restart_work);
@@ -1089,7 +1078,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1089 wiphy_warn(local->hw.wiphy, "skb_queue not empty\n"); 1078 wiphy_warn(local->hw.wiphy, "skb_queue not empty\n");
1090 skb_queue_purge(&local->skb_queue); 1079 skb_queue_purge(&local->skb_queue);
1091 skb_queue_purge(&local->skb_queue_unreliable); 1080 skb_queue_purge(&local->skb_queue_unreliable);
1092 skb_queue_purge(&local->rx_skb_queue);
1093 1081
1094 destroy_workqueue(local->workqueue); 1082 destroy_workqueue(local->workqueue);
1095 wiphy_unregister(local->hw.wiphy); 1083 wiphy_unregister(local->hw.wiphy);