mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 18:09:56 +00:00
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: 69a0fcf8a9 ("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
This commit is contained in:
committed by
Kalle Valo
parent
7004bdceef
commit
cf2df0080b
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user