wifi: rtw88: increase TX report timeout to fix race condition
Subsystems (2)
PATCH v2 1/1 wifi: rtw88: increase TX report timeout to fix race condition
From: Luka Gejak <[email protected]>
The driver expects the firmware to report TX status within 500ms. However, a timeout can be triggered when the hardware performs background scans while under TX load. During these scans, the firmware stays off-channel for periods exceeding 500ms, delaying the delivery of TX reports back to the driver.
When this occurs, the purge timer fires prematurely and drops the tracking skbs from the queue. This results in the host stack interpreting the missing status as packet loss, leading to TCP window collapse. In testing with iperf3, this causes throughput to drop from ~90 Mbps to near-zero for approximately 2 seconds until the connection recovers.
Increase RTW_TX_PROBE_TIMEOUT to 2500ms for RTL8723DU. This duration is sufficient to accommodate off-channel dwell time during full background scans, ensuring the purge timer only trips during genuine firmware lockups and preventing unnecessary TCP retransmission cycles.
---
Changes in v2:
-Isolated the change to RTL8723DU as requested by Ping-Ke
drivers/net/wireless/realtek/rtw88/tx.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw88/tx.c +8 -1
@@ -196,6 +196,7 @@ void rtw_tx_report_purge_timer(struct timer_list *t)void rtw_tx_report_enqueue (struct rtw_dev *rtwdev,struct sk_buff *skb,u8 sn) {struct rtw_tx_report *tx_report = &rtwdev->tx_report; +unsigned long timeout;unsigned long flags;u8 *drv_data;
@@ -207,7 +208,13 @@ void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)__skb_queue_tail (&tx_report->queue, skb);spin_unlock_irqrestore (&tx_report->q_lock, flags); -mod_timer (&tx_report->purge_timer, jiffies +RTW_TX_PROBE_TIMEOUT ); +if (rtwdev->chip->id ==RTW_CHIP_TYPE_8723D && + rtwdev->hci.type ==RTW_HCI_TYPE_USB ) + timeout =msecs_to_jiffies (2500 ); +else + timeout =RTW_TX_PROBE_TIMEOUT ; + +mod_timer (&tx_report->purge_timer, jiffies + timeout); }EXPORT_SYMBOL (rtw_tx_report_enqueue);
Signature · 1 line
2.54.0
Ping-Ke Shih
maintainerQuoted 15 lines · [email protected] <[email protected]> wrote:
From: Luka Gejak <[email protected]>
The driver expects the firmware to report TX status within 500ms. However, a timeout can be triggered when the hardware performs background scans while under TX load. During these scans, the firmware stays off-channel for periods exceeding 500ms, delaying the delivery of TX reports back to the driver.
When this occurs, the purge timer fires prematurely and drops the tracking skbs from the queue. This results in the host stack interpreting the missing status as packet loss, leading to TCP window collapse. In testing with iperf3, this causes throughput to drop from ~90 Mbps to near-zero for approximately 2 seconds until the connection recovers.
Quoted 6 lines
Increase
RTW_TX_PROBE_TIMEOUTto 2500ms for RTL8723DU. This duration is sufficient to accommodate off-channel dwell time during full background scans, ensuring the purge timer only trips during genuine firmware lockups and preventing unnecessary TCP retransmission cycles.Fixes e3037485c68e ("rtw88: new Realtek 802.11ac driver")
I don't think this commit introduce USB support.
Quoted 15 lines
Tested-by Luka Gejak <[email protected]>Signed-off-by Luka Gejak <[email protected]>---
Changes in v2:
-Isolated the change to RTL8723DU as requested by Ping-Kedrivers/net/wireless/realtek/rtw88/tx.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)drivers/net/wireless/realtek/rtw88/tx.c +0
-0
drivers/net/wireless/realtek/rtw88/tx.c void rtw_tx_report_purge_timer(struct timer_list *t) · line 199
Quoted 4 lines
drivers/net/wireless/realtek/rtw88/tx.c +1
-0@@ -196,6 +196,7 @@ void rtw_tx_report_purge_timer(struct timer_list *t)void rtw_tx_report_enqueue (struct rtw_dev *rtwdev,struct sk_buff *skb,u8 sn) {struct rtw_tx_report *tx_report = &rtwdev->tx_report; +unsigned long timeout;
Declare RTW_TX_PROBE_TIMEOUT as default value.
unsigned long timeout = RTW_TX_PROBE_TIMEOUT;
drivers/net/wireless/realtek/rtw88/tx.c void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn) · line 213
Quoted 11 lines
drivers/net/wireless/realtek/rtw88/tx.c +3
-1unsigned long flags;u8 *drv_data;@@ -207,7 +208,13 @@ void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)__skb_queue_tail (&tx_report->queue, skb);spin_unlock_irqrestore (&tx_report->q_lock, flags); -mod_timer (&tx_report->purge_timer, jiffies +RTW_TX_PROBE_TIMEOUT ); +if (rtwdev->chip->id ==RTW_CHIP_TYPE_8723D && + rtwdev->hci.type ==RTW_HCI_TYPE_USB ) + timeout =msecs_to_jiffies (2500 );
Only RTL8723DU uses different setting treated as an exception by if-condition.
Quoted 9 lines
drivers/net/wireless/realtek/rtw88/tx.c +4
-1+else + timeout =RTW_TX_PROBE_TIMEOUT ; + +mod_timer (&tx_report->purge_timer, jiffies + timeout); }EXPORT_SYMBOL (rtw_tx_report_enqueue); --2.54.0