Re: [PATCH 2/2] wifi: ath10k: Flush only requested txq in ath10k_flush()

From: Vasanthakumar Thiagarajan
Date: Fri Oct 18 2024 - 12:19:44 EST




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