diff mbox series

[v6,03/13] wifi: ath11k: fix a possible dead lock caused by ab->base_lock

Message ID 20230920082349.29111-4-quic_wgong@quicinc.com (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show
Series wifi: ath11k: add support for 6 GHz station for various modes : LPI, SP and VLP | expand

Commit Message

Wen Gong Sept. 20, 2023, 8:23 a.m. UTC
From: Baochen Qiang <quic_bqiang@quicinc.com>

spin_lock/spin_unlock are used in ath11k_reg_chan_list_event to
acquire/release ab->base_lock, for now this is safe because that
function is only called in soft IRQ context.

But ath11k_reg_chan_list_event() will be called from process
context in an upcoming patch, and this can result in a deadlock if
ab->base_lock is acquired in process context and then soft IRQ occurs
on the same CPU and tries to acquire that lock.

Fix it by using spin_lock_bh and spin_unlock_bh instead.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23

Fixes: 69a0fcf8a9f2 ("ath11k: Avoid reg rules update during firmware recovery")
Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
---
 drivers/net/wireless/ath/ath11k/wmi.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Jeff Johnson Sept. 21, 2023, 7:54 p.m. UTC | #1
On 9/20/2023 1:23 AM, Wen Gong wrote:
> From: Baochen Qiang <quic_bqiang@quicinc.com>
> 
> spin_lock/spin_unlock are used in ath11k_reg_chan_list_event to
> acquire/release ab->base_lock, for now this is safe because that

Kalle, can you s/, for/. For/ when you pull into pending?

> function is only called in soft IRQ context.
> 
> But ath11k_reg_chan_list_event() will be called from process
> context in an upcoming patch, and this can result in a deadlock if
> ab->base_lock is acquired in process context and then soft IRQ occurs
> on the same CPU and tries to acquire that lock.
> 
> Fix it by using spin_lock_bh and spin_unlock_bh instead.
> 
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23
> 
> Fixes: 69a0fcf8a9f2 ("ath11k: Avoid reg rules update during firmware recovery")
> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
> Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Kalle Valo Sept. 25, 2023, 10:35 a.m. UTC | #2
Jeff Johnson <quic_jjohnson@quicinc.com> writes:

> On 9/20/2023 1:23 AM, Wen Gong wrote:
>> From: Baochen Qiang <quic_bqiang@quicinc.com>
>> spin_lock/spin_unlock are used in ath11k_reg_chan_list_event to
>> acquire/release ab->base_lock, for now this is safe because that
>
> Kalle, can you s/, for/. For/ when you pull into pending?

Yes, will do. BTW to save time for simple edits like this I don't always
reply to you, I just do the edit the silently. In case you wonder if why
I don't reply.
Kalle Valo Oct. 2, 2023, 3:51 p.m. UTC | #3
Wen Gong <quic_wgong@quicinc.com> wrote:

> spin_lock/spin_unlock are used in ath11k_reg_chan_list_event to
> acquire/release ab->base_lock, for now this is safe because that
> function is only called in soft IRQ context.
> 
> But ath11k_reg_chan_list_event() will be called from process
> context in an upcoming patch, and this can result in a deadlock if
> ab->base_lock is acquired in process context and then soft IRQ occurs
> on the same CPU and tries to acquire that lock.
> 
> Fix it by using spin_lock_bh and spin_unlock_bh instead.
> 
> Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23
> 
> Fixes: 69a0fcf8a9f2 ("ath11k: Avoid reg rules update during firmware recovery")
> Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
> Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
> Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>

This patch seems to leak memory:

unreferenced object 0xffff8881110f5840 (size 64):
  comm "softirq", pid 0, jiffies 4295335213 (age 79.445s)
  hex dump (first 32 bytes):
    32 14 82 14 50 00 17 00 00 02 00 00 82 14 d2 14  2...P...........
    50 00 17 00 08 02 00 00 72 15 62 16 a0 00 1e 00  P.......r.b.....
  backtrace:
    [<ffffffffa1f891ca>] __kmem_cache_alloc_node+0x1ca/0x2d0
    [<ffffffffa1e57950>] __kmalloc+0x50/0x1a0
    [<ffffffffc076640e>] create_ext_reg_rules_from_wmi+0x2e/0x430 [ath11k]
    [<ffffffffc07705c4>] ath11k_pull_reg_chan_list_ext_update_ev+0x1d24/0x4f30 [ath11k]
    [<ffffffffc07a4a44>] ath11k_reg_chan_list_event.isra.0+0x64/0xd0 [ath11k]
    [<ffffffffc07a562f>] ath11k_wmi_tlv_op_rx+0xb7f/0x27e0 [ath11k]
    [<ffffffffc07f3a54>] ath11k_htc_rx_completion_handler+0x3b4/0x6f0 [ath11k]
    [<ffffffffc0838b3a>] ath11k_ce_recv_process_cb+0x5da/0x920 [ath11k]
    [<ffffffffc0839b68>] ath11k_ce_per_engine_service+0xe8/0x130 [ath11k]
    [<ffffffffc084ba75>] ath11k_pcic_ce_tasklet+0x65/0x120 [ath11k]
    [<ffffffffa196df5c>] tasklet_action_common.isra.0+0x24c/0x3d0
    [<ffffffffa196e12f>] tasklet_action+0x4f/0x70
    [<ffffffffa448b355>] __do_softirq+0x1c5/0x867
unreferenced object 0xffff8881110f5f40 (size 64):
  comm "softirq", pid 0, jiffies 4295335238 (age 79.439s)
  hex dump (first 32 bytes):
    32 14 82 14 50 00 17 00 00 02 00 00 82 14 d2 14  2...P...........
    50 00 17 00 08 02 00 00 72 15 62 16 a0 00 1e 00  P.......r.b.....
  backtrace:
    [<ffffffffa1f891ca>] __kmem_cache_alloc_node+0x1ca/0x2d0
    [<ffffffffa1e57950>] __kmalloc+0x50/0x1a0
    [<ffffffffc076640e>] create_ext_reg_rules_from_wmi+0x2e/0x430 [ath11k]
    [<ffffffffc07705c4>] ath11k_pull_reg_chan_list_ext_update_ev+0x1d24/0x4f30 [ath11k]
    [<ffffffffc07a4a44>] ath11k_reg_chan_list_event.isra.0+0x64/0xd0 [ath11k]
    [<ffffffffc07a562f>] ath11k_wmi_tlv_op_rx+0xb7f/0x27e0 [ath11k]
    [<ffffffffc07f3a54>] ath11k_htc_rx_completion_handler+0x3b4/0x6f0 [ath11k]
    [<ffffffffc0838b3a>] ath11k_ce_recv_process_cb+0x5da/0x920 [ath11k]
    [<ffffffffc0839b68>] ath11k_ce_per_engine_service+0xe8/0x130 [ath11k]
    [<ffffffffc084ba75>] ath11k_pcic_ce_tasklet+0x65/0x120 [ath11k]
    [<ffffffffa196df5c>] tasklet_action_common.isra.0+0x24c/0x3d0
    [<ffffffffa196e12f>] tasklet_action+0x4f/0x70
    [<ffffffffa448b355>] __do_softirq+0x1c5/0x867
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
index 1fb445106872..c427299b7202 100644
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -7138,13 +7138,13 @@  int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
 	/* Avoid default reg rule updates sent during FW recovery if
 	 * it is already available
 	 */
-	spin_lock(&ab->base_lock);
+	spin_lock_bh(&ab->base_lock);
 	if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) &&
 	    ab->default_regd[pdev_idx]) {
-		spin_unlock(&ab->base_lock);
+		spin_unlock_bh(&ab->base_lock);
 		goto retfail;
 	}
-	spin_unlock(&ab->base_lock);
+	spin_unlock_bh(&ab->base_lock);
 
 	if (pdev_idx >= ab->num_radios) {
 		/* Process the event for phy0 only if single_pdev_only
@@ -7194,7 +7194,7 @@  int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
 		ab->reg_info_store[pdev_idx] = *reg_info;
 	}
 
-	spin_lock(&ab->base_lock);
+	spin_lock_bh(&ab->base_lock);
 	if (ab->default_regd[pdev_idx]) {
 		/* The initial rules from FW after WMI Init is to build
 		 * the default regd. From then on, any rules updated for
@@ -7214,7 +7214,7 @@  int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
 		ab->default_regd[pdev_idx] = regd;
 	}
 	ab->dfs_region = reg_info->dfs_region;
-	spin_unlock(&ab->base_lock);
+	spin_unlock_bh(&ab->base_lock);
 
 	return 0;