summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-03-12 19:28:31 +0100
committerJohannes Berg <johannes.berg@intel.com>2015-03-30 09:46:52 +0200
commit2c158887f1185e04b3763ae346da9f71fcbc4429 (patch)
treec8ade2c50b86dc7b802b8d74a7064543721dd027
parent5d8325ecb9c21015f330eb0dcffcc5fc1b1fe5b8 (diff)
mac80211: agg-tx: avoid sending DelBA with sta->lock held
The rate control locking caused a potential deadlock here due to the locks being acquired in different orders, so that change cannot yet be applied. However, there's no fundamental reason for this code to hold the sta->lock while transmitting frames. Clearly it's better not to hold the lock for longer periods of time, which can happen here since we call all the way down to the driver. Change the code a bit to not hold it while doing that. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/agg-tx.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index a360c15cc978..668524aeb0b2 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -793,6 +793,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
struct tid_ampdu_tx *tid_tx;
+ bool send_delba = false;
trace_api_stop_tx_ba_cb(sdata, ra, tid);
@@ -824,13 +825,17 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
}
if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop)
- ieee80211_send_delba(sta->sdata, ra, tid,
- WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
+ send_delba = true;
ieee80211_remove_tid_tx(sta, tid);
unlock_sta:
spin_unlock_bh(&sta->lock);
+
+ if (send_delba)
+ ieee80211_send_delba(sdata, ra, tid,
+ WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
+
mutex_unlock(&sta->ampdu_mlme.mtx);
unlock:
mutex_unlock(&local->sta_mtx);