Linux-mediatek Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] wifi: mt76: mt7603: bound the frames a station keeps in the hardware
@ 2026-09-23 13:22 Cristian Papa
  2026-09-23 13:22 ` [RFC PATCH 1/2] wifi: mt76: let a driver hold a station's tx queues Cristian Papa
  2026-09-23 13:22 ` [RFC PATCH 2/2] wifi: mt76: mt7603: bound the frames a station keeps in the hardware Cristian Papa
  0 siblings, 2 replies; 3+ messages in thread
From: Cristian Papa @ 2026-09-23 13:22 UTC (permalink / raw)
  To: linux-wireless
  Cc: nbd, lorenzo, ryder.lee, shayne.chen, sean.wang, linux-mediatek

mt7603 completes a frame to mac80211 as soon as DMA has copied it, so
AQL never sees the frames the hardware still holds for a station. On a
TP-Link Archer XR500v (EN751221 + MT7603E) with one client, counters
added to upstream mt76 showed the hardware holding about 200 frames for
a single downloading client, nearly the whole 256-entry tx ring, and up
to 740 under bidirectional load.

With a client that toggles PM often (here a Samsung Galaxy A56 with
Bluetooth on, which enters power save several times per second under
load), every PS entry loops all of those frames back to the host, and
the PS queue keeps only 64 of them. The frames freed per second roughly
matched the client's TCP retransmissions per second.

The series holds a station's tx queues while the hardware owes it too
many TX statuses (a new MT_WCID_FLAG_TX_HOLD, honoured by the mt76 tx
scheduler like the non-AQL limit), and sizes the PS queue so that what
the hardware loops back fits. It depends on "wifi: mt76: mt7603: don't
drop short frames looped back on PS entry" [1], without which the count
leaks one frame for every BlockAck request that is looped back.

This is an RFC because I am not sure a driver-side hold is the approach
you want. Questions:

- Would you rather keep the airtime of each frame accounted until its TX
  status, so that AQL sees what the hardware holds, instead of a count
  in the driver?
- The marks (hold at 96, release at 48) and the PS queue size (tx ring
  minus 64) were tuned with one client only.
- If a held station sees neither a TX status nor a loop-back return for
  a second, its count is reset. In the tests below this happened 0 to 3
  times in 30 minutes, probably when the client slept for more than a
  second with frames still in the hardware. Is there a better signal?
- The raw re-send of the PS queue on wake-up bypasses the hold, so the
  count can briefly exceed the high mark (up to 134 here).

Either change alone makes things worse, which is why the cap and the PS
queue size are one patch. In a 30 minute bidirectional test (iperf3
-P 4, one client, a ping from a wired host every 200 ms) that cycled
through the four combinations every minute, about 7 minutes each:

                          upstream  bigger PSQ     cap  cap + PSQ
  frames in hw (max)           748         844      98        134
  PSQ frees per second          92         213      51          0
  downlink Mbit/s             12.2        15.2    10.6       17.0
  seconds without downlink      45         108     111         10
  longest stall (s)             10          53      16          1
  retransmits per second      15.4         8.9    10.2        3.0
  uplink Mbit/s               64.0        60.7    63.8       59.3
  ping median/p99 (ms)     119/339    145/2915 125/482    130/292
  pings lost                  6.0%       13.7%    7.5%      0.13%

The stalls come in bursts of PM toggling, with up to 22-28 PS entries
per second. In the worst stretch, the minute with the cap and the
bigger queue had 2 seconds without downlink progress, against 20, 41 and
39 in the neighbouring minutes of the other combinations.

Two shorter runs toggled the cap alone (PS queue of 64) every 30
seconds, over 60 seconds of download and 300 of bidirectional traffic,
with a 2.4 GHz wireless headset dongle nearby. In the download phases,
with the cap: PSQ frees went from 59.5 to 7.3 and from 54.5 to 5.3 per
second, retransmits from 54.9 to 8.2 and from 58.8 to 9.1 per second,
the ping median from 38 to 23 and from 32 to 25 ms, and throughput from
56 to 61 and from 59 to 63 Mbit/s. Bidirectional retransmits went from
13.5 to 6.0 and from 13.8 to 8.3 per second.

Testing: OpenWrt with kernel 6.18.41 and the mac80211 backport of
6.18.39, openwrt/mt76 at be5ce79105 plus [1], this series, the board's
local patches (EEPROM file from DT, two crash fixes, beacon stall
recovery, fixes for the mt76x2e radio) and debugfs counters that are
not part of the series. AP on channel 1, HT20. One device and one client
only: no MT7628/MT7688, and nothing with several busy stations. The
series is against wireless-next; on openwrt/mt76, where it was built
and tested, patch 1 only differs in context (mt76_wcid_primary() in the
non-AQL check).

[1] https://lore.kernel.org/linux-wireless/20260922220814.15070-1-pcristian292@gmail.com/

Tools: an AI coding assistant (Claude Opus 5.5 in Claude Code) wrote the
instrumentation, analyzed the data, and drafted these patches and this
letter; the tests ran on my device.

Cristian Papa (2):
  wifi: mt76: let a driver hold a station's tx queues
  wifi: mt76: mt7603: bound the frames a station keeps in the hardware

 drivers/net/wireless/mediatek/mt76/mt76.h     |  1 +
 .../wireless/mediatek/mt76/mt7603/debugfs.c   | 32 ++++++++++
 .../net/wireless/mediatek/mt76/mt7603/dma.c   |  7 ++-
 .../net/wireless/mediatek/mt76/mt7603/init.c  |  2 +
 .../net/wireless/mediatek/mt76/mt7603/mac.c   | 58 +++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7603/main.c  | 20 +++++--
 .../wireless/mediatek/mt76/mt7603/mt7603.h    | 51 ++++++++++++++++
 drivers/net/wireless/mediatek/mt76/tx.c       |  7 +++
 8 files changed, 172 insertions(+), 6 deletions(-)


base-commit: 10cfa109c880092df32e396647b4afdca9be8350
prerequisite-patch-id: b2c7fb85fb032bec084c6e325be32ea1172af916
-- 
2.47.3



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-23 13:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-23 13:22 [RFC PATCH 0/2] wifi: mt76: mt7603: bound the frames a station keeps in the hardware Cristian Papa
2026-09-23 13:22 ` [RFC PATCH 1/2] wifi: mt76: let a driver hold a station's tx queues Cristian Papa
2026-09-23 13:22 ` [RFC PATCH 2/2] wifi: mt76: mt7603: bound the frames a station keeps in the hardware Cristian Papa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox