On 10/12/2024 7:43 PM, Remi Pommarel wrote:
The ieee80211 flush callback can be called to flush only part of all hw queues. The ath10k's flush callback implementation (i.e. ath10k_flush()) was waiting for all pending frames of all queues to be flushed ignoring the queue parameter. Because only the queues to be flushed are stopped by mac80211, skb can still be queued to other queues meanwhile. Thus ath10k_flush() could fail (and wait 5sec holding ar->conf lock) even if the requested queues are flushed correctly. A way to reproduce the issue is to use two different APs because each vdev has its own hw queue in ath10k. Connect STA0 to AP0 and STA1 to AP1. Then generate traffic from AP0 to STA0 and kill STA0 without clean disassociation frame (e.g. unplug power cable, reboot -f, ...). Now if we were to flush AP1's queue, ath10k_flush() would fail (and effectively block 5 seconds with ar->conf or even wiphy's lock held) with the following warning: ath10k_pci 0000:01:00.0: failed to flush transmit queue (skip 0 ar-state 2): 0 Wait only for pending frames of the requested queues to be flushed in ath10k_flush() to avoid that long blocking. Reported-by: Cedric Veilleux <veilleux.cedric@xxxxxxxxx> Signed-off-by: Remi Pommarel <repk@xxxxxxxxxxxx> --- drivers/net/wireless/ath/ath10k/htt.h | 7 +++-- drivers/net/wireless/ath/ath10k/htt_tx.c | 18 ++++++++++--- drivers/net/wireless/ath/ath10k/mac.c | 33 +++++++++++++++++------- drivers/net/wireless/ath/ath10k/txrx.c | 2 +- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index d150f9330941..33054fc4d9fb 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -1870,6 +1870,7 @@ struct ath10k_htt { spinlock_t tx_lock; int max_num_pending_tx; int num_pending_tx; + int pending_per_queue[IEEE80211_MAX_QUEUES];
Something like num_pending_per_queue[] to align with the existing packet counter looks better? Vasanth