[RFC PATCH 0/1] Avoid per WMI message tb allocation

Nicolas Escande
2026-02-26T16:55:23Z

So for a bit of context I have devices that have memory allocation
faillures when parsing WMI messages such as bellow:

[73277.177015] swapper/0: page allocation failure: order:2, mode:0x40920(GFP_ATOMIC|__GFP_COMP|__GFP_ZERO), nodemask=(null)
[73277.177035] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted XXX #109
[73277.177040] Hardware name: XXX
[73277.177043] Call trace:
[73277.177045] show_stack+0x14/0x20 (C)
[73277.177054] dump_stack_lvl+0x58/0x74
[73277.177058] dump_stack+0x14/0x1c
[73277.177061] warn_alloc+0xd4/0x150
[73277.177065] __alloc_pages_noprof+0x688/0xa10
[73277.177068] ___kmalloc_large_node+0x64/0xf8
[73277.177072] __kmalloc_large_noprof+0x10/0x20
[73277.177075] ath12k_wmi_tlv_parse_alloc.constprop.0+0x24/0x90 [ath12k]
[73277.177095] ath12k_wmi_op_rx+0x658/0x2624 [ath12k]
[73277.177111] ath12k_htc_rx_completion_handler+0x464/0x660 [ath12k]
[73277.177125] ath12k_ce_per_engine_service+0x2dc/0x3ec [ath12k]
[73277.177140] ath12k_pci_ce_workqueue+0x30/0x50 [ath12k]
[73277.177155] process_one_work+0x154/0x2e0
[73277.177160] bh_worker+0x1dc/0x228
[73277.177164] workqueue_softirq_action+0x74/0x80
[73277.177168] tasklet_action+0x10/0x40
[73277.177172] handle_softirqs+0xfc/0x240
[73277.177175] __do_softirq+0x10/0x18
[73277.177178] ____do_softirq+0xc/0x20
...

So it seems that parsing a a WMI TLV requires an array of WMI_TAG_MAX
(void *). This array is then populated with pointers of parsed structs
depending on the WMI type. This alloc happens on a per WMI message, in
softirq, using GFP_ATOMIC which puts pressure on the kernel allocator and
can fail.

I'm not very familliar but from my understanding of the system_bh_wq, we
can have at most one work item per CPU running this code path. So the
following patch aims changes the code to have a per cpu array instead to
parse the WMI msg and thus avoiding dynamic allocation.

What do you think ? Is this the right way forward ?

Nicolas Escande (1):
wifi: ath12k: avoid dynamic alloc when parsing wmi tb

drivers/net/wireless/ath/ath12k/core.c | 7 +
drivers/net/wireless/ath/ath12k/core.h | 2 +
drivers/net/wireless/ath/ath12k/wmi.c | 170 ++++++-------------------
3 files changed, 49 insertions(+), 130 deletions(-)

--
2.53.0