mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-23 17:47:28 +08:00
55 lines
2.2 KiB
Diff
55 lines
2.2 KiB
Diff
From 2db80f93869d491be57cbc2b36f30d0d3a0e5bde Mon Sep 17 00:00:00 2001
|
|
From: Niels Dossche <dossche.niels@gmail.com>
|
|
Date: Mon, 21 Mar 2022 12:58:23 +0200
|
|
Subject: [PATCH] ath11k: acquire ab->base_lock in unassign when finding the
|
|
peer by addr
|
|
|
|
ath11k_peer_find_by_addr states via lockdep that ab->base_lock must be
|
|
held when calling that function in order to protect the list. All
|
|
callers except ath11k_mac_op_unassign_vif_chanctx have that lock
|
|
acquired when calling ath11k_peer_find_by_addr. That lock is also not
|
|
transitively held by a path towards ath11k_mac_op_unassign_vif_chanctx.
|
|
The solution is to acquire the lock when calling
|
|
ath11k_peer_find_by_addr inside ath11k_mac_op_unassign_vif_chanctx.
|
|
|
|
I am currently working on a static analyser to detect missing locks and
|
|
this was a reported case. I manually verified the report by looking at
|
|
the code, but I do not have real hardware so this is compile tested
|
|
only.
|
|
|
|
Fixes: 701e48a43e15 ("ath11k: add packet log support for QCA6390")
|
|
Signed-off-by: Niels Dossche <dossche.niels@gmail.com>
|
|
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
|
|
Link: https://lore.kernel.org/r/20220314215253.92658-1-dossche.niels@gmail.com
|
|
---
|
|
drivers/net/wireless/ath/ath11k/mac.c | 11 ++++++++---
|
|
1 file changed, 8 insertions(+), 3 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -7133,6 +7133,7 @@ ath11k_mac_op_unassign_vif_chanctx(struc
|
|
struct ath11k *ar = hw->priv;
|
|
struct ath11k_base *ab = ar->ab;
|
|
struct ath11k_vif *arvif = (void *)vif->drv_priv;
|
|
+ struct ath11k_peer *peer;
|
|
int ret;
|
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
@@ -7144,9 +7145,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc
|
|
WARN_ON(!arvif->is_started);
|
|
|
|
if (ab->hw_params.vdev_start_delay &&
|
|
- arvif->vdev_type == WMI_VDEV_TYPE_MONITOR &&
|
|
- ath11k_peer_find_by_addr(ab, ar->mac_addr))
|
|
- ath11k_peer_delete(ar, arvif->vdev_id, ar->mac_addr);
|
|
+ arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
|
+ spin_lock_bh(&ab->base_lock);
|
|
+ peer = ath11k_peer_find_by_addr(ab, ar->mac_addr);
|
|
+ spin_unlock_bh(&ab->base_lock);
|
|
+ if (peer)
|
|
+ ath11k_peer_delete(ar, arvif->vdev_id, ar->mac_addr);
|
|
+ }
|
|
|
|
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
|
ret = ath11k_mac_monitor_stop(ar);
|