[PATCH rtw-next 3/3] wifi: rtw88: reset the stations outside of RCU on firmware recovery
From: Mehmet Fide
Date: Wed Nov 11 2026 - 16:33:43 EST
From: Mehmet Fide <mehmet.fide@xxxxxxxxxxxxxxxxxx>
The recovery after a firmware crash removes the driver state of every
station with rtw_sta_remove(), called from an atomic station iterator.
rtw_sta_remove() cancels the rate work of the station with
cancel_work_sync(), which can sleep. With a station associated:
BUG: sleeping function called from invalid context at kernel/workqueue.c:4722
in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 14, name: kworker/u16:1
RCU nest depth: 1, expected: 0
Workqueue: phy35 rtw_fw_recovery_work [rtw88_core]
Call trace:
__might_resched+0x13c/0x1f0
__might_sleep+0x48/0x7c
__cancel_work_sync+0xa8/0xb4
cancel_work_sync+0x14/0x20
rtw_sta_remove+0x34/0x10c [rtw88_core]
rtw_reset_sta_iter+0x20/0x48 [rtw88_core]
ieee80211_iterate_stations_atomic+0x80/0x144 [mac80211]
rtw_fw_recovery_work+0x1dc/0x2b8 [rtw88_core]
Use rtw_iterate_stas(), which collects the stations under RCU and calls
the iterator after it. The recovery holds the driver mutex it asks for.
Fixes: bcafcb959a57 ("wifi: rtw88: use work to update rate to avoid RCU warning")
Signed-off-by: Mehmet Fide <mehmet.fide@xxxxxxxxxxxxxxxxxx>
---
drivers/net/wireless/realtek/rtw88/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index ce65a1a80840..8e7ae747b900 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -664,7 +664,7 @@ static void __fw_recovery_work(struct rtw_dev *rtwdev)
WARN(1, "firmware crash, start reset and recover\n");
rtw_iterate_keys_atomic(rtwdev, NULL, rtw_reset_key_iter, rtwdev);
- rtw_iterate_stas_atomic(rtwdev, rtw_reset_sta_iter, rtwdev);
+ rtw_iterate_stas(rtwdev, rtw_reset_sta_iter, rtwdev);
rtw_iterate_vifs_atomic(rtwdev, rtw_reset_vif_iter, rtwdev);
bitmap_zero(rtwdev->hw_port, RTW_PORT_NUM);
rtw_enter_ips(rtwdev);
--
2.56.0