Message ID | 20230718024724.29120-1-quic_wgong@quicinc.com |
---|---|
State | New |
Headers | show |
Series | wifi: ath12k: avoid deadlock by change ieee80211_queue_work for regd_update_work | expand |
Wen Gong <quic_wgong@quicinc.com> wrote: > Deadlock is easily happened while shutdown wlan interface such as run > "ifconfig wlan0 down". > > The reason is because when ar->regd_update_work is ran, it will > call wiphy_lock(ar->hw->wiphy) in function ath12k_regd_update() which > is running in workqueue of ieee80211_local queued by ieee80211_queue_work(). > Another thread from "ifconfig wlan0 down" will also accuqire the lock > by wiphy_lock(sdata->local->hw.wiphy) in function ieee80211_stop(), and > then it call ieee80211_stop_device() to flush_workqueue(local->workqueue), > this will wait the workqueue of ieee80211_local finished. Then deadlock > will happen easily if the two thread run meanwhile. > > Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4 > > Signed-off-by: Wen Gong <quic_wgong@quicinc.com> > Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Patch applied to ath-next branch of ath.git, thanks. 8198950ccb7d wifi: ath12k: avoid deadlock by change ieee80211_queue_work for regd_update_work
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 7ae0bb78b2b5..ea6de84bf5cd 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -5213,7 +5213,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk ar = ab->pdevs[pdev_idx].ar; kfree(ab->new_regd[pdev_idx]); ab->new_regd[pdev_idx] = regd; - ieee80211_queue_work(ar->hw, &ar->regd_update_work); + queue_work(ab->workqueue, &ar->regd_update_work); } else { /* Multiple events for the same *ar is not expected. But we * can still clear any previously stored default_regd if we
Deadlock is easily happened while shutdown wlan interface such as run "ifconfig wlan0 down". The reason is because when ar->regd_update_work is ran, it will call wiphy_lock(ar->hw->wiphy) in function ath12k_regd_update() which is running in workqueue of ieee80211_local queued by ieee80211_queue_work(). Another thread from "ifconfig wlan0 down" will also accuqire the lock by wiphy_lock(sdata->local->hw.wiphy) in function ieee80211_stop(), and then it call ieee80211_stop_device() to flush_workqueue(local->workqueue), this will wait the workqueue of ieee80211_local finished. Then deadlock will happen easily if the two thread run meanwhile. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4 Signed-off-by: Wen Gong <quic_wgong@quicinc.com> --- drivers/net/wireless/ath/ath12k/wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) base-commit: 0a00db612b6df1fad80485e3642529d1f28ea084