summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath11k
diff options
context:
space:
mode:
authorBaochen Qiang <quic_bqiang@quicinc.com>2024-01-11 16:56:57 +0300
committerKalle Valo <quic_kvalo@quicinc.com>2024-01-14 17:59:08 +0300
commitcf2df0080bd59cb97a1519ddefaf59788febdaa5 (patch)
tree3b04ecd32cd376aa4a52756d9a792828b96eda1e /drivers/net/wireless/ath/ath11k
parent7004bdceef605e5c1c5ab4aaf282002ad7523ddd (diff)
downloadlinux-cf2df0080bd59cb97a1519ddefaf59788febdaa5.tar.xz
wifi: ath11k: fix a possible dead lock caused by ab->base_lock
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> Link: https://msgid.link/20231218085844.2658-4-quic_bqiang@quicinc.com
Diffstat (limited to 'drivers/net/wireless/ath/ath11k')
-rw-r--r--drivers/net/wireless/ath/ath11k/reg.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
index adcd9063a59c..d4fd3509e608 100644
--- a/drivers/net/wireless/ath/ath11k/reg.c
+++ b/drivers/net/wireless/ath/ath11k/reg.c
@@ -852,13 +852,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
@@ -911,7 +911,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
@@ -931,7 +931,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;