wifi: ath12k: fix a possible dead lock caused by ab->base_lock

[ Upstream commit ef115c265a21e3c11deee7f73bd1061775a7bf20 ]

spin_lock/spin_unlock are used in ath12k_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 ath12k_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: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250418-ath12k-6g-lp-vlp-v1-1-c869c86cad60@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Baochen Qiang
2025-04-18 10:55:34 +08:00
committed by Greg Kroah-Hartman
parent 7c4b6d8bd7
commit dcf7bb4397

View File

@@ -5503,7 +5503,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
goto fallback; goto fallback;
} }
spin_lock(&ab->base_lock); spin_lock_bh(&ab->base_lock);
if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) { if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) {
/* Once mac is registered, ar is valid and all CC events from /* Once mac is registered, ar is valid and all CC events from
* fw is considered to be received due to user requests * fw is considered to be received due to user requests
@@ -5527,7 +5527,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
ab->default_regd[pdev_idx] = regd; ab->default_regd[pdev_idx] = regd;
} }
ab->dfs_region = reg_info->dfs_region; ab->dfs_region = reg_info->dfs_region;
spin_unlock(&ab->base_lock); spin_unlock_bh(&ab->base_lock);
goto mem_free; goto mem_free;