Skip to content

Commit 007ae9b

Browse files
alexw65500jmberg-intel
authored andcommitted
wifi: mac80211: Serialize ieee80211_handle_wake_tx_queue()
ieee80211_handle_wake_tx_queue must not run concurrent multiple times. It calls ieee80211_txq_schedule_start() and the drivers migrated to iTXQ do not expect overlapping drv_tx() calls. This fixes 'c850e31f79f0 ("wifi: mac80211: add internal handler for wake_tx_queue")', which introduced ieee80211_handle_wake_tx_queue. Drivers started to use it with 'a790cc3a4fad ("wifi: mac80211: add wake_tx_queue callback to drivers")'. But only after fixing an independent bug with '4444bc2116ae ("wifi: mac80211: Proper mark iTXQs for resumption")' problematic concurrent calls really happened and exposed the initial issue. Fixes: c850e31 ("wifi: mac80211: add internal handler for wake_tx_queue") Reported-by: Thomas Mann <[email protected]> Link: https://bugzilla.kernel.org/show_bug.cgi?id=217119 Link: https://lore.kernel.org/r/[email protected]/ Link: https://lore.kernel.org/r/[email protected]> CC: <[email protected]> Signed-off-by: Alexander Wetzel <[email protected]> Link: https://lore.kernel.org/r/[email protected] [add missing spin_lock_init() noticed by Felix] Signed-off-by: Johannes Berg <[email protected]>
1 parent 139f697 commit 007ae9b

File tree

3 files changed

+8
-0
lines changed

3 files changed

+8
-0
lines changed

net/mac80211/ieee80211_i.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,9 @@ struct ieee80211_local {
12841284
struct list_head active_txqs[IEEE80211_NUM_ACS];
12851285
u16 schedule_round[IEEE80211_NUM_ACS];
12861286

1287+
/* serializes ieee80211_handle_wake_tx_queue */
1288+
spinlock_t handle_wake_tx_queue_lock;
1289+
12871290
u16 airtime_flags;
12881291
u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
12891292
u32 aql_txq_limit_high[IEEE80211_NUM_ACS];

net/mac80211/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
802802
local->aql_threshold = IEEE80211_AQL_THRESHOLD;
803803
atomic_set(&local->aql_total_pending_airtime, 0);
804804

805+
spin_lock_init(&local->handle_wake_tx_queue_lock);
806+
805807
INIT_LIST_HEAD(&local->chanctx_list);
806808
mutex_init(&local->chanctx_mtx);
807809

net/mac80211/util.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,16 @@ void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
314314
struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
315315
struct ieee80211_txq *queue;
316316

317+
spin_lock(&local->handle_wake_tx_queue_lock);
318+
317319
/* Use ieee80211_next_txq() for airtime fairness accounting */
318320
ieee80211_txq_schedule_start(hw, txq->ac);
319321
while ((queue = ieee80211_next_txq(hw, txq->ac))) {
320322
wake_tx_push_queue(local, sdata, queue);
321323
ieee80211_return_txq(hw, queue, false);
322324
}
323325
ieee80211_txq_schedule_end(hw, txq->ac);
326+
spin_unlock(&local->handle_wake_tx_queue_lock);
324327
}
325328
EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue);
326329

0 commit comments

Comments
 (0)