[PATCH ath-next v2 1/5] wifi: ath11k: initialise the CE descriptor waitqueue once per device
From: Julius Bairaktaris
Date: Sun Oct 18 2026 - 17:03:45 EST
Firmware crash recovery reinitialises tx_ce_desc_wq in
ath11k_connect_pdev_htc_service(), reached through ath11k_core_start()
and ath11k_wmi_connect(), while a WMI command on a device without credit
flow can still sleep on it in ath11k_wmi_cmd_send(). finish_wait() then
unlinks the waiter from the reset list head:
list_del corruption. prev->next should be ffffffc084293648, but was
ffffff80075109a8. (prev=ffffff80075109a8)
WARNING: CPU: 2 PID: 1782 at lib/list_debug.c:62
__list_del_entry_valid_or_report+0x134/0x174
CPU: 2 UID: 101 PID: 1782 Comm: hostapd
Call trace:
__list_del_entry_valid_or_report+0x134/0x174 (P)
finish_wait+0x68/0xb8
ath11k_wmi_cmd_send+0x150/0x2f4 [ath11k]
ath11k_wmi_vdev_set_param_cmd+0x64/0xd8 [ath11k]
ath11k_mac_op_bss_info_changed+0xe8/0xf6c [ath11k]
drv_link_info_changed+0x128/0x180 [mac80211]
ieee80211_link_info_change_notify+0xe0/0x100 [mac80211]
ieee80211_change_bss+0x1bc/0x250 [mac80211]
nl80211_set_bss+0x1a0/0x328 [cfg80211]
Initialise the queues once in ath11k_core_alloc().
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.9.0.1-02146-QCAHKSWPL_SILICONZ-1
Fixes: f951380a6022 ("ath11k: Disabling credit flow for WMI path")
Reviewed-by: Baochen Qiang <baochen.qiang@xxxxxxxxxxxxxxxx>
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Julius Bairaktaris <julius@xxxxxxxxxxxxxx>
---
drivers/net/wireless/ath/ath11k/core.c | 5 +++++
drivers/net/wireless/ath/ath11k/wmi.c | 1 -
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
index 766ae27306f43..8e4dab61a3009 100644
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -2743,6 +2743,7 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
enum ath11k_bus bus)
{
struct ath11k_base *ab;
+ int i;
ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
if (!ab)
@@ -2769,6 +2770,10 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
INIT_LIST_HEAD(&ab->peers);
init_waitqueue_head(&ab->peer_mapping_wq);
init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
+
+ for (i = 0; i < ARRAY_SIZE(ab->wmi_ab.wmi); i++)
+ init_waitqueue_head(&ab->wmi_ab.wmi[i].tx_ce_desc_wq);
+
init_waitqueue_head(&ab->qmi.cold_boot_waitq);
INIT_WORK(&ab->restart_work, ath11k_core_restart);
INIT_WORK(&ab->update_11d_work, ath11k_update_11d);
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 08fd6795ed9e7..3d5b6605eace8 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -9101,7 +9101,6 @@ static int ath11k_connect_pdev_htc_service(struct ath11k_base *ab,
ab->wmi_ab.wmi_endpoint_id[pdev_idx] = conn_resp.eid;
ab->wmi_ab.wmi[pdev_idx].eid = conn_resp.eid;
ab->wmi_ab.max_msg_len[pdev_idx] = conn_resp.max_msg_len;
- init_waitqueue_head(&ab->wmi_ab.wmi[pdev_idx].tx_ce_desc_wq);
return 0;
}
--
2.53.0