* [PATCH rtw-next 0/3] wifi: rtw88: three fixes around the firmware recovery
@ 2026-11-11 21:32 Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 1/3] wifi: rtw88: free the reserved pages of an interface on " Mehmet Fide
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Mehmet Fide @ 2026-11-11 21:32 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: Tzu-En Huang, Yan-Hsuan Chuang, Kalle Valo, Stanislaw Gruszka,
Brian Norris, linux-wireless, linux-kernel, mehmet.fide
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
Three fixes for what a firmware crash test showed on an RTL8822CE.
They are independent of the channel switch series.
Tested on rtw-next (04c998418722) on an i.MX8MP board with
PROVE_LOCKING, DEBUG_ATOMIC_SLEEP and kmemleak, with hostapd. The
firmware crashes were triggered from debugfs on the RTL8822CE:
- patch 1: three crashes with an associated station interface lost
five reserved pages before and none after; six crashes with an AP
interface lost three before and none after
- patch 2: an unbind after the crashes warned "Have pending ack
frames!" before and did not after. With a test build that drops
every TX report of the firmware, the unbind of the RTL8822CE warned
before; after, neither it nor the RTL8822BU did
- patch 3: each of three crashes with an associated station gave the
"sleeping function called from invalid context" report before and
none did after; the link was back after every crash
With the three patches, AP, association, power save, firmware crash
and scan tests on the RTL8822CE, RTL8822CU, RTL8822BU and RTL8821CU on
both bands gave no kernel report.
Mehmet Fide (3):
wifi: rtw88: free the reserved pages of an interface on firmware
recovery
wifi: rtw88: report the frames purged from the TX report queue
wifi: rtw88: reset the stations outside of RCU on firmware recovery
drivers/net/wireless/realtek/rtw88/main.c | 8 +++-----
drivers/net/wireless/realtek/rtw88/tx.c | 20 ++++++++++++++++----
drivers/net/wireless/realtek/rtw88/tx.h | 1 +
3 files changed, 20 insertions(+), 9 deletions(-)
base-commit: 04c9984187228904f222681661c50db3f0c50b71
--
2.56.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH rtw-next 1/3] wifi: rtw88: free the reserved pages of an interface on firmware recovery
2026-11-11 21:32 [PATCH rtw-next 0/3] wifi: rtw88: three fixes around the firmware recovery Mehmet Fide
@ 2026-11-11 21:32 ` Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 2/3] wifi: rtw88: report the frames purged from the TX report queue Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 3/3] wifi: rtw88: reset the stations outside of RCU on firmware recovery Mehmet Fide
2 siblings, 0 replies; 4+ messages in thread
From: Mehmet Fide @ 2026-11-11 21:32 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: Tzu-En Huang, Yan-Hsuan Chuang, Kalle Valo, Stanislaw Gruszka,
Brian Norris, linux-wireless, linux-kernel, mehmet.fide
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
The recovery after a firmware crash resets the driver state of every
interface, and mac80211 then adds the interfaces again without removing
them first. rtw_ops_add_interface() starts with an empty reserved page
list, so the pages the interface had before the crash are lost: the
next page build takes them off the build list and nothing frees them.
kmemleak after a firmware crash with an AP interface:
unreferenced object 0xffff0000cbe22c60 (size 96):
comm "hostapd", pid 25545, jiffies 4296463067
backtrace (crc cbdc21c4):
kmemleak_alloc+0xcc/0xe4
__kmalloc_cache_noprof+0x234/0x3bc
rtw_add_rsvd_page+0x38/0xa8 [rtw88_core]
rtw_add_rsvd_page_bcn+0x30/0x58 [rtw88_core]
rtw_ops_add_interface+0x144/0x2cc [rtw88_core]
rtw_ops_change_interface+0x6c/0x80 [rtw88_core]
drv_change_interface+0x100/0x258 [mac80211]
Free the pages where the recovery resets the interface.
Fixes: 5c831644e1f4 ("rtw88: handle and recover when firmware crash")
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index f7708ad17b6f..adc54b063382 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -627,6 +627,7 @@ static void rtw_reset_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
rtw_bf_disassoc(rtwdev, vif, NULL);
rtw_vif_assoc_changed(rtwvif, NULL);
rtw_txq_cleanup(rtwdev, vif->txq);
+ rtw_remove_rsvd_page(rtwdev, rtwvif);
rtw_release_macid(rtwdev, rtwvif->mac_id);
}
--
2.56.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH rtw-next 2/3] wifi: rtw88: report the frames purged from the TX report queue
2026-11-11 21:32 [PATCH rtw-next 0/3] wifi: rtw88: three fixes around the firmware recovery Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 1/3] wifi: rtw88: free the reserved pages of an interface on " Mehmet Fide
@ 2026-11-11 21:32 ` Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 3/3] wifi: rtw88: reset the stations outside of RCU on firmware recovery Mehmet Fide
2 siblings, 0 replies; 4+ messages in thread
From: Mehmet Fide @ 2026-11-11 21:32 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: Tzu-En Huang, Yan-Hsuan Chuang, Kalle Valo, Stanislaw Gruszka,
Brian Norris, linux-wireless, linux-kernel, mehmet.fide
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
A frame whose sender asked for its TX status waits in the TX report
queue for the report of the firmware. When no report comes, the purge
timer frees the frames with skb_queue_purge(), and rtw_core_deinit()
does the same. mac80211 is not told: the sender gets no status, and the
copy mac80211 keeps for the status of a frame from user space stays in
its list until ieee80211_free_hw() warns about it. On an RTL8822CE with
hostapd, after a firmware crash and an unbind of the driver:
rtw88_8822ce 0000:01:00.0: failed to get tx report from firmware
[...]
Have pending ack frames!
WARNING: net/mac80211/main.c:1761 at ieee80211_free_ack_frame+0x4c/0x70 [mac80211], CPU#1: sh/24725
Call trace:
ieee80211_free_ack_frame+0x4c/0x70 [mac80211] (P)
idr_for_each+0x6c/0xf4
ieee80211_free_hw+0x30/0x8c [mac80211]
rtw_pci_remove+0xd8/0xf0 [rtw88_pci]
pci_device_remove+0x44/0xd4
Take the frames off the queue under its lock and hand them to
ieee80211_purge_tx_queue(), which reports each one as not sent.
Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver")
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
---
drivers/net/wireless/realtek/rtw88/main.c | 5 +----
drivers/net/wireless/realtek/rtw88/tx.c | 20 ++++++++++++++++----
drivers/net/wireless/realtek/rtw88/tx.h | 1 +
3 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index adc54b063382..ce65a1a80840 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -2225,7 +2225,6 @@ void rtw_core_deinit(struct rtw_dev *rtwdev)
struct rtw_fw_state *fw = &rtwdev->fw;
struct rtw_fw_state *wow_fw = &rtwdev->wow_fw;
struct rtw_rsvd_page *rsvd_pkt, *tmp;
- unsigned long flags;
rtw_wait_firmware_completion(rtwdev);
@@ -2237,9 +2236,7 @@ void rtw_core_deinit(struct rtw_dev *rtwdev)
destroy_workqueue(rtwdev->tx_wq);
timer_delete_sync(&rtwdev->tx_report.purge_timer);
- spin_lock_irqsave(&rtwdev->tx_report.q_lock, flags);
- skb_queue_purge(&rtwdev->tx_report.queue);
- spin_unlock_irqrestore(&rtwdev->tx_report.q_lock, flags);
+ rtw_tx_report_purge(rtwdev);
skb_queue_purge(&rtwdev->coex.queue);
skb_queue_purge(&rtwdev->c2h_queue);
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 701ed7c4f3f7..87d993282b1c 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -176,21 +176,33 @@ static void rtw_tx_report_enable(struct rtw_dev *rtwdev,
pkt_info->report = true;
}
+void rtw_tx_report_purge(struct rtw_dev *rtwdev)
+{
+ struct rtw_tx_report *tx_report = &rtwdev->tx_report;
+ struct sk_buff_head purge;
+ unsigned long flags;
+
+ __skb_queue_head_init(&purge);
+
+ spin_lock_irqsave(&tx_report->q_lock, flags);
+ skb_queue_splice_init(&tx_report->queue, &purge);
+ spin_unlock_irqrestore(&tx_report->q_lock, flags);
+
+ ieee80211_purge_tx_queue(rtwdev->hw, &purge);
+}
+
void rtw_tx_report_purge_timer(struct timer_list *t)
{
struct rtw_dev *rtwdev = timer_container_of(rtwdev, t,
tx_report.purge_timer);
struct rtw_tx_report *tx_report = &rtwdev->tx_report;
- unsigned long flags;
if (skb_queue_len(&tx_report->queue) == 0)
return;
rtw_warn(rtwdev, "failed to get tx report from firmware\n");
- spin_lock_irqsave(&tx_report->q_lock, flags);
- skb_queue_purge(&tx_report->queue);
- spin_unlock_irqrestore(&tx_report->q_lock, flags);
+ rtw_tx_report_purge(rtwdev);
}
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)
diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h
index 168f48e87853..363f63525965 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -98,6 +98,7 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
struct sk_buff *skb);
void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev,
struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb);
+void rtw_tx_report_purge(struct rtw_dev *rtwdev);
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn);
void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src);
void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev,
--
2.56.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH rtw-next 3/3] wifi: rtw88: reset the stations outside of RCU on firmware recovery
2026-11-11 21:32 [PATCH rtw-next 0/3] wifi: rtw88: three fixes around the firmware recovery Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 1/3] wifi: rtw88: free the reserved pages of an interface on " Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 2/3] wifi: rtw88: report the frames purged from the TX report queue Mehmet Fide
@ 2026-11-11 21:32 ` Mehmet Fide
2 siblings, 0 replies; 4+ messages in thread
From: Mehmet Fide @ 2026-11-11 21:32 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: Tzu-En Huang, Yan-Hsuan Chuang, Kalle Valo, Stanislaw Gruszka,
Brian Norris, linux-wireless, linux-kernel, mehmet.fide
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
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@screeningeagle.com>
---
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
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-11 21:32 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11 21:32 [PATCH rtw-next 0/3] wifi: rtw88: three fixes around the firmware recovery Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 1/3] wifi: rtw88: free the reserved pages of an interface on " Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 2/3] wifi: rtw88: report the frames purged from the TX report queue Mehmet Fide
2026-11-11 21:32 ` [PATCH rtw-next 3/3] wifi: rtw88: reset the stations outside of RCU on firmware recovery Mehmet Fide
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®