aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-rx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2010-04-19 05:00:24 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-19 16:41:42 -0400
commit2aab4c273ad837fbcf2955aee32b9ec4706c2521 (patch)
treed2457aa623177d2b7c18b35a81f91ac268699999 /net/mac80211/agg-rx.c
parent93d95b12b3ba06e0e1f3e43a370ee61539d8cb90 (diff)
mac80211: fix stopping RX BA session from timer
Kalle reported that his system deadlocks since my recent work in this area. The reason quickly became apparent: we try to cancel_timer_sync() a timer from within itself. Fix that by making the function aware of the context it is called from. Reported-by: Kalle Valo <kvalo@adurom.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Tested-by: Kalle Valo <kvalo@adurom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/agg-rx.c')
-rw-r--r--net/mac80211/agg-rx.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 53233ab50f65..1771dd9bd137 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -18,8 +18,9 @@
18#include "ieee80211_i.h" 18#include "ieee80211_i.h"
19#include "driver-ops.h" 19#include "driver-ops.h"
20 20
21void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 21static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
22 u16 initiator, u16 reason) 22 u16 initiator, u16 reason,
23 bool from_timer)
23{ 24{
24 struct ieee80211_local *local = sta->local; 25 struct ieee80211_local *local = sta->local;
25 struct tid_ampdu_rx *tid_rx; 26 struct tid_ampdu_rx *tid_rx;
@@ -69,10 +70,17 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
69 70
70 spin_unlock_bh(&sta->lock); 71 spin_unlock_bh(&sta->lock);
71 72
72 del_timer_sync(&tid_rx->session_timer); 73 if (!from_timer)
74 del_timer_sync(&tid_rx->session_timer);
73 kfree(tid_rx); 75 kfree(tid_rx);
74} 76}
75 77
78void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
79 u16 initiator, u16 reason)
80{
81 ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, false);
82}
83
76/* 84/*
77 * After accepting the AddBA Request we activated a timer, 85 * After accepting the AddBA Request we activated a timer,
78 * resetting it after each frame that arrives from the originator. 86 * resetting it after each frame that arrives from the originator.
@@ -91,8 +99,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
91#ifdef CONFIG_MAC80211_HT_DEBUG 99#ifdef CONFIG_MAC80211_HT_DEBUG
92 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); 100 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
93#endif 101#endif
94 __ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT, 102 ___ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT,
95 WLAN_REASON_QSTA_TIMEOUT); 103 WLAN_REASON_QSTA_TIMEOUT, true);
96} 104}
97 105
98static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, 106static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,