* [PATCH 1/2] wifi: ath11k: initialize txmgmt_empty_waitq before registering the hw
2026-10-08 22:58 [PATCH ath-next 0/2] wifi: ath11k: fix two races between ieee80211_register_hw() and the rest of mac registration Nikolay Bryskin
@ 2026-10-08 22:58 ` Nikolay Bryskin
2026-10-08 22:58 ` [PATCH 2/2] wifi: ath11k: apply the initial regdomain before registering the wiphy Nikolay Bryskin
1 sibling, 0 replies; 3+ messages in thread
From: Nikolay Bryskin @ 2026-10-08 22:58 UTC (permalink / raw)
To: jjohnson; +Cc: ath11k, linux-wireless, johannes, Nikolay Bryskin
ath11k_mac_register() initializes ar->txmgmt_empty_waitq only after
__ath11k_mac_register() has returned, but __ath11k_mac_register() calls
ieee80211_register_hw(). From that point on userspace can transmit
management frames (iwd starts authenticating as soon as the wiphy shows
up), and a WMI mgmt TX completion event then ends up in
wmi_process_mgmt_tx_comp(), which calls wake_up() on the not yet
initialized wait queue head:
BUG: kernel NULL pointer dereference, address: 0000000000000000
RIP: 0010:__wake_up+0x5a/0xf0
Call Trace:
<IRQ>
ath11k_wmi_tlv_op_rx+0x174c/0x32b0 [ath11k]
ath11k_htc_rx_completion_handler+0x4fd/0x670 [ath11k]
ath11k_ce_per_engine_service+0x2b2/0x380 [ath11k]
ath11k_pcic_ce_tasklet+0x1d/0x40 [ath11k]
tasklet_action_common+0x186/0x290
handle_softirqs+0xe8/0x2a0
...
Kernel panic - not syncing: Fatal exception in interrupt
The window is normally very short. The panic above was hit at boot with
an msleep(2000) inserted after ieee80211_register_hw() for testing, while
iwd authenticated to an AP during the delay.
Initialize the wait queue together with the rest of the txmgmt state,
before registering, as ath12k already does.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-05266-QCAHSTSWPLZ_V2_TO_X86-1
Fixes: dddaa64d0af3 ("ath11k: add wait operation for tx management packets for flush from mac80211")
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Nikolay Bryskin <nbryskin@gmail.com>
---
drivers/net/wireless/ath/ath11k/mac.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index c1fa42edd363..3dfd24d7b5a6 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -10738,12 +10738,11 @@ int ath11k_mac_register(struct ath11k_base *ab)
idr_init(&ar->txmgmt_idr);
spin_lock_init(&ar->txmgmt_idr_lock);
+ init_waitqueue_head(&ar->txmgmt_empty_waitq);
ret = __ath11k_mac_register(ar);
if (ret)
goto err_cleanup;
-
- init_waitqueue_head(&ar->txmgmt_empty_waitq);
}
return 0;
--
2.56.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 2/2] wifi: ath11k: apply the initial regdomain before registering the wiphy
2026-10-08 22:58 [PATCH ath-next 0/2] wifi: ath11k: fix two races between ieee80211_register_hw() and the rest of mac registration Nikolay Bryskin
2026-10-08 22:58 ` [PATCH 1/2] wifi: ath11k: initialize txmgmt_empty_waitq before registering the hw Nikolay Bryskin
@ 2026-10-08 22:58 ` Nikolay Bryskin
1 sibling, 0 replies; 3+ messages in thread
From: Nikolay Bryskin @ 2026-10-08 22:58 UTC (permalink / raw)
To: jjohnson; +Cc: ath11k, linux-wireless, johannes, Nikolay Bryskin
ath11k marks its wiphy REGULATORY_WIPHY_SELF_MANAGED in
ath11k_reg_init(), but applies the regdomain received from the firmware
only after ieee80211_register_hw(), and asynchronously:
regulatory_set_wiphy_regd() just stores the request and schedules
reg_work. Userspace is told about the new wiphy from wiphy_register(), so
it can query the regdomain before there is one. iwd does exactly that as
soon as the wiphy appears, which triggers the WARN_ON() in
nl80211_get_reg_do():
!regdom && self_managed
WARNING: net/wireless/nl80211.c:10576 at nl80211_get_reg_do+0x229/0x270 [cfg80211], CPU#4: iwd/716
Call Trace:
genl_family_rcv_msg_doit+0x144/0x1a0
genl_rcv_msg+0x1cc/0x300
netlink_rcv_skb+0xcd/0x150
genl_rcv+0x28/0x40
netlink_unicast+0x2fb/0x4a0
netlink_sendmsg+0x219/0x480
__sys_sendto+0x226/0x230
...
The regdomain is already known at that point (ab->default_regd[], or
ab->new_regd[] if an update arrived meanwhile), so apply it before
ieee80211_register_hw(). wiphy_register() then installs the pending
regdomain itself, via wiphy_regulatory_register() ->
reg_process_self_managed_hints(). That happens under the same RTNL hold
as the NL80211_CMD_NEW_WIPHY notification, and nl80211_get_reg_do() takes
the RTNL as well, so userspace can no longer see the wiphy without its
regdomain.
The window matters beyond the warning. With an msleep(2000) inserted
after ieee80211_register_hw() for testing, iwd associated before the
regdomain was applied; the late regdomain then went through
ath11k_reg_notifier() ("driver initiated regd update") and the channel
list update to the firmware while associated, and from then on TX was
badly degraded while RX stayed fine (QCA6390, 5 GHz DFS channel, signal
-33 dBm, no beacon loss):
tx packets: 2012, tx failed: 1678, tx retries: 0
tx bitrate: 48.0 MBit/s
rx bitrate: 648.5 MBit/s 80MHz HE-MCS 6 HE-NSS 2
ping showed 39% loss. Without the delay, the WARN_ON() shows up at boot
only occasionally. With this patch and the same delay neither the
warning nor the TX degradation occurred.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-05266-QCAHSTSWPLZ_V2_TO_X86-1
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Link: https://lore.kernel.org/all/16aa99921c4e92e8d4da3c84aacbec2e673666aa.camel@sipsolutions.net/
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Nikolay Bryskin <nbryskin@gmail.com>
---
drivers/net/wireless/ath/ath11k/mac.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 3dfd24d7b5a6..4ebdde872213 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -10648,6 +10648,16 @@ static int __ath11k_mac_register(struct ath11k *ar)
ab->hw_params.bios_sar_capa)
ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa;
+ /* Apply the regd received during initialization. Do it before
+ * registering so that cfg80211 installs it while registering the
+ * wiphy, before userspace can query a self-managed wiphy without one.
+ */
+ ret = ath11k_regd_update(ar);
+ if (ret) {
+ ath11k_err(ar->ab, "ath11k regd update failed: %d\n", ret);
+ goto err_free_if_combs;
+ }
+
ret = ieee80211_register_hw(ar->hw);
if (ret) {
ath11k_err(ar->ab, "ieee80211 registration failed: %d\n", ret);
@@ -10662,13 +10672,6 @@ static int __ath11k_mac_register(struct ath11k *ar)
*/
ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);
- /* Apply the regd received during initialization */
- ret = ath11k_regd_update(ar);
- if (ret) {
- ath11k_err(ar->ab, "ath11k regd update failed: %d\n", ret);
- goto err_unregister_hw;
- }
-
if (ab->hw_params.current_cc_support && ab->new_alpha2[0]) {
memcpy(&ar->alpha2, ab->new_alpha2, 2);
ret = ath11k_reg_set_cc(ar);
--
2.56.0
^ permalink raw reply related [flat|nested] 3+ messages in thread