| From 24f50a9d165745fd0701c6e089d35f58a229ea69 Mon Sep 17 00:00:00 2001 |
| From: Johannes Berg <johannes.berg@intel.com> |
| Date: Thu, 24 Nov 2011 20:06:14 +0100 |
| Subject: mac80211: don't stop a single aggregation session twice |
| |
| From: Johannes Berg <johannes.berg@intel.com> |
| |
| commit 24f50a9d165745fd0701c6e089d35f58a229ea69 upstream. |
| |
| Nikolay noticed (by code review) that mac80211 can |
| attempt to stop an aggregation session while it is |
| already being stopped. So to fix it, check whether |
| stop is already being done and bail out if so. |
| |
| Also move setting the STOPPING state into the lock |
| so things are properly atomic. |
| |
| Reported-by: Nikolay Martynov <mar.kolya@gmail.com> |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: John W. Linville <linville@tuxdriver.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| net/mac80211/agg-tx.c | 10 ++++++++-- |
| 1 file changed, 8 insertions(+), 2 deletions(-) |
| |
| --- a/net/mac80211/agg-tx.c |
| +++ b/net/mac80211/agg-tx.c |
| @@ -162,6 +162,12 @@ int ___ieee80211_stop_tx_ba_session(stru |
| return -ENOENT; |
| } |
| |
| + /* if we're already stopping ignore any new requests to stop */ |
| + if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { |
| + spin_unlock_bh(&sta->lock); |
| + return -EALREADY; |
| + } |
| + |
| if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { |
| /* not even started yet! */ |
| ieee80211_assign_tid_tx(sta, tid, NULL); |
| @@ -170,6 +176,8 @@ int ___ieee80211_stop_tx_ba_session(stru |
| return 0; |
| } |
| |
| + set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); |
| + |
| spin_unlock_bh(&sta->lock); |
| |
| #ifdef CONFIG_MAC80211_HT_DEBUG |
| @@ -177,8 +185,6 @@ int ___ieee80211_stop_tx_ba_session(stru |
| sta->sta.addr, tid); |
| #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| |
| - set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); |
| - |
| del_timer_sync(&tid_tx->addba_resp_timer); |
| |
| /* |