Browse Source

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>
Johannes Berg 10 years ago
parent
commit
2c158887f1
1 changed files with 7 additions and 2 deletions
  1. 7 2
      net/mac80211/agg-tx.c

+ 7 - 2
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 ieee80211_local *local = sdata->local;
 	struct sta_info *sta;
 	struct sta_info *sta;
 	struct tid_ampdu_tx *tid_tx;
 	struct tid_ampdu_tx *tid_tx;
+	bool send_delba = false;
 
 
 	trace_api_stop_tx_ba_cb(sdata, ra, tid);
 	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)
 	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);
 	ieee80211_remove_tid_tx(sta, tid);
 
 
  unlock_sta:
  unlock_sta:
 	spin_unlock_bh(&sta->lock);
 	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);
 	mutex_unlock(&sta->ampdu_mlme.mtx);
  unlock:
  unlock:
 	mutex_unlock(&local->sta_mtx);
 	mutex_unlock(&local->sta_mtx);