661f4bbfbf147f060e9add74ed8df189fab4cd12
[openwrt/staging/neocturne.git] /
1 From f74878433d5ade360447da5d92e9c2e535780d80 Mon Sep 17 00:00:00 2001
2 From: Wen Gong <quic_wgong@quicinc.com>
3 Date: Wed, 28 Sep 2022 03:38:32 -0400
4 Subject: [PATCH] wifi: ath11k: fix warning in dma_free_coherent() of memory
5 chunks while recovery
6
7 Commit 26f3a021b37c ("ath11k: allocate smaller chunks of memory for
8 firmware") and commit f6f92968e1e5 ("ath11k: qmi: try to allocate a
9 big block of DMA memory first") change ath11k to allocate the memory
10 chunks for target twice while wlan load. It fails for the 1st time
11 because of large memory and then changed to allocate many small chunks
12 for the 2nd time sometimes as below log.
13
14 1st time failed:
15 [10411.640620] ath11k_pci 0000:05:00.0: qmi firmware request memory request
16 [10411.640625] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 6881280
17 [10411.640630] ath11k_pci 0000:05:00.0: qmi mem seg type 4 size 3784704
18 [10411.640658] ath11k_pci 0000:05:00.0: qmi dma allocation failed (6881280 B type 1), will try later with small size
19 [10411.640671] ath11k_pci 0000:05:00.0: qmi delays mem_request 2
20 [10411.640677] ath11k_pci 0000:05:00.0: qmi respond memory request delayed 1
21 2nd time success:
22 [10411.642004] ath11k_pci 0000:05:00.0: qmi firmware request memory request
23 [10411.642008] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
24 [10411.642012] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
25 [10411.642014] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
26 [10411.642016] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
27 [10411.642018] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
28 [10411.642020] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
29 [10411.642022] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
30 [10411.642024] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
31 [10411.642027] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
32 [10411.642029] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
33 [10411.642031] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 458752
34 [10411.642033] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 131072
35 [10411.642035] ath11k_pci 0000:05:00.0: qmi mem seg type 4 size 524288
36 [10411.642037] ath11k_pci 0000:05:00.0: qmi mem seg type 4 size 524288
37 [10411.642039] ath11k_pci 0000:05:00.0: qmi mem seg type 4 size 524288
38 [10411.642041] ath11k_pci 0000:05:00.0: qmi mem seg type 4 size 524288
39 [10411.642043] ath11k_pci 0000:05:00.0: qmi mem seg type 4 size 524288
40 [10411.642045] ath11k_pci 0000:05:00.0: qmi mem seg type 4 size 524288
41 [10411.642047] ath11k_pci 0000:05:00.0: qmi mem seg type 4 size 491520
42 [10411.642049] ath11k_pci 0000:05:00.0: qmi mem seg type 1 size 524288
43
44 And then commit 5962f370ce41 ("ath11k: Reuse the available memory after
45 firmware reload") skip the ath11k_qmi_free_resource() which frees the
46 memory chunks while recovery, after that, when run recovery test on
47 WCN6855, a warning happened every time as below and finally leads fail
48 for recovery.
49
50 [ 159.570318] BUG: Bad page state in process kworker/u16:5 pfn:33300
51 [ 159.570320] page:0000000096ffdbb9 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x33300
52 [ 159.570324] flags: 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff)
53 [ 159.570329] raw: 000fffffc0000000 0000000000000000 dead000000000122 0000000000000000
54 [ 159.570332] raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
55 [ 159.570334] page dumped because: nonzero _refcount
56 [ 159.570440] firewire_ohci syscopyarea sysfillrect psmouse sdhci_pci ahci sysimgblt firewire_core fb_sys_fops libahci crc_itu_t cqhci drm sdhci e1000e wmi video
57 [ 159.570460] CPU: 2 PID: 217 Comm: kworker/u16:5 Kdump: loaded Tainted: G B 5.19.0-rc1-wt-ath+ #3
58 [ 159.570465] Hardware name: LENOVO 418065C/418065C, BIOS 83ET63WW (1.33 ) 07/29/2011
59 [ 159.570467] Workqueue: qmi_msg_handler qmi_data_ready_work [qmi_helpers]
60 [ 159.570475] Call Trace:
61 [ 159.570476] <TASK>
62 [ 159.570478] dump_stack_lvl+0x49/0x5f
63 [ 159.570486] dump_stack+0x10/0x12
64 [ 159.570493] bad_page+0xab/0xf0
65 [ 159.570502] check_free_page_bad+0x66/0x70
66 [ 159.570511] __free_pages_ok+0x530/0x9a0
67 [ 159.570517] ? __dev_printk+0x58/0x6b
68 [ 159.570525] ? _dev_printk+0x56/0x72
69 [ 159.570534] ? qmi_decode+0x119/0x470 [qmi_helpers]
70 [ 159.570543] __free_pages+0x91/0xd0
71 [ 159.570548] dma_free_contiguous+0x50/0x60
72 [ 159.570556] dma_direct_free+0xe5/0x140
73 [ 159.570564] dma_free_attrs+0x35/0x50
74 [ 159.570570] ath11k_qmi_msg_mem_request_cb+0x2ae/0x3c0 [ath11k]
75 [ 159.570620] qmi_invoke_handler+0xac/0xe0 [qmi_helpers]
76 [ 159.570630] qmi_handle_message+0x6d/0x180 [qmi_helpers]
77 [ 159.570643] qmi_data_ready_work+0x2ca/0x440 [qmi_helpers]
78 [ 159.570656] process_one_work+0x227/0x440
79 [ 159.570667] worker_thread+0x31/0x3d0
80 [ 159.570676] ? process_one_work+0x440/0x440
81 [ 159.570685] kthread+0xfe/0x130
82 [ 159.570692] ? kthread_complete_and_exit+0x20/0x20
83 [ 159.570701] ret_from_fork+0x22/0x30
84 [ 159.570712] </TASK>
85
86 The reason is because when wlan start to recovery, the type, size and
87 count is not same for the 1st and 2nd QMI_WLFW_REQUEST_MEM_IND message,
88 Then it leads the parameter size is not correct for the dma_free_coherent().
89 For the chunk[1], the actual dma size is 524288 which allocate in the
90 2nd time of the initial wlan load phase, and the size which pass to
91 dma_free_coherent() is 3784704 which is got in the 1st time of recovery
92 phase, then warning above happened.
93
94 Change to use prev_size of struct target_mem_chunk for the paramter of
95 dma_free_coherent() since prev_size is the real size of last load/recovery.
96 Also change to check both type and size of struct target_mem_chunk to
97 reuse the memory to avoid mismatch buffer size for target. Then the
98 warning disappear and recovery success. When the 1st QMI_WLFW_REQUEST_MEM_IND
99 for recovery arrived, the trunk[0] is freed in ath11k_qmi_alloc_target_mem_chunk()
100 and then dma_alloc_coherent() failed caused by large size, and then
101 trunk[1] is freed in ath11k_qmi_free_target_mem_chunk(), the left 18
102 trunks will be reuse for the 2nd QMI_WLFW_REQUEST_MEM_IND message.
103
104 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
105
106 Fixes: 5962f370ce41 ("ath11k: Reuse the available memory after firmware reload")
107 Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
108 Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
109 Link: https://lore.kernel.org/r/20220928073832.16251-1-quic_wgong@quicinc.com
110 ---
111 drivers/net/wireless/ath/ath11k/qmi.c | 6 +++---
112 1 file changed, 3 insertions(+), 3 deletions(-)
113
114 --- a/drivers/net/wireless/ath/ath11k/qmi.c
115 +++ b/drivers/net/wireless/ath/ath11k/qmi.c
116 @@ -1961,7 +1961,7 @@ static void ath11k_qmi_free_target_mem_c
117 continue;
118
119 dma_free_coherent(ab->dev,
120 - ab->qmi.target_mem[i].size,
121 + ab->qmi.target_mem[i].prev_size,
122 ab->qmi.target_mem[i].vaddr,
123 ab->qmi.target_mem[i].paddr);
124 ab->qmi.target_mem[i].vaddr = NULL;
125 @@ -1982,12 +1982,12 @@ static int ath11k_qmi_alloc_target_mem_c
126 * in such case, no need to allocate memory for FW again.
127 */
128 if (chunk->vaddr) {
129 - if (chunk->prev_type == chunk->type ||
130 + if (chunk->prev_type == chunk->type &&
131 chunk->prev_size == chunk->size)
132 continue;
133
134 /* cannot reuse the existing chunk */
135 - dma_free_coherent(ab->dev, chunk->size,
136 + dma_free_coherent(ab->dev, chunk->prev_size,
137 chunk->vaddr, chunk->paddr);
138 chunk->vaddr = NULL;
139 }