Skip to content

Commit 06c41bd

Browse files
committed
mac80211: agg-tx: don't schedule_and_wake_txq() under sta->lock
When we call ieee80211_agg_start_txq(), that will in turn call schedule_and_wake_txq(). Called from ieee80211_stop_tx_ba_cb() this is done under sta->lock, which leads to certain circular lock dependencies, as reported by Chris Murphy: https://lore.kernel.org/r/CAJCQCtSXJ5qA4bqSPY=oLRMbv-irihVvP7A2uGutEbXQVkoNaw@mail.gmail.com In general, ieee80211_agg_start_txq() is usually not called with sta->lock held, only in this one place. But it's always called with sta->ampdu_mlme.mtx held, and that's therefore clearly sufficient. Change ieee80211_stop_tx_ba_cb() to also call it without the sta->lock held, by factoring it out of ieee80211_remove_tid_tx() (which is only called in this one place). This breaks the locking chain and makes it less likely that we'll have similar locking chain problems in the future. Fixes: ba8c3d6 ("mac80211: add an intermediate software queue implementation") Reported-by: Chris Murphy <lists@colorremedies.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/iwlwifi.20211202152554.f519884c8784.I555fef8e67d93fff3d9a304886c4a9f8b322e591@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent 37d3311 commit 06c41bd

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

net/mac80211/agg-tx.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
1010
* Copyright 2007-2010, Intel Corporation
1111
* Copyright(c) 2015-2017 Intel Deutschland GmbH
12-
* Copyright (C) 2018 - 2020 Intel Corporation
12+
* Copyright (C) 2018 - 2021 Intel Corporation
1313
*/
1414

1515
#include <linux/ieee80211.h>
@@ -213,6 +213,8 @@ ieee80211_agg_start_txq(struct sta_info *sta, int tid, bool enable)
213213
struct ieee80211_txq *txq = sta->sta.txq[tid];
214214
struct txq_info *txqi;
215215

216+
lockdep_assert_held(&sta->ampdu_mlme.mtx);
217+
216218
if (!txq)
217219
return;
218220

@@ -290,7 +292,6 @@ static void ieee80211_remove_tid_tx(struct sta_info *sta, int tid)
290292
ieee80211_assign_tid_tx(sta, tid, NULL);
291293

292294
ieee80211_agg_splice_finish(sta->sdata, tid);
293-
ieee80211_agg_start_txq(sta, tid, false);
294295

295296
kfree_rcu(tid_tx, rcu_head);
296297
}
@@ -889,6 +890,7 @@ void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
889890
{
890891
struct ieee80211_sub_if_data *sdata = sta->sdata;
891892
bool send_delba = false;
893+
bool start_txq = false;
892894

893895
ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n",
894896
sta->sta.addr, tid);
@@ -906,10 +908,14 @@ void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
906908
send_delba = true;
907909

908910
ieee80211_remove_tid_tx(sta, tid);
911+
start_txq = true;
909912

910913
unlock_sta:
911914
spin_unlock_bh(&sta->lock);
912915

916+
if (start_txq)
917+
ieee80211_agg_start_txq(sta, tid, false);
918+
913919
if (send_delba)
914920
ieee80211_send_delba(sdata, sta->sta.addr, tid,
915921
WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);

0 commit comments

Comments
 (0)