diff options
author | Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com> | 2011-11-01 07:08:50 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2011-11-11 05:59:00 -0500 |
commit | 11f6e40d9f21767a9090e4e559d3c63edf25e6c0 (patch) | |
tree | c3fd39804436cc897756271f3fd1e6ba0d2a53db /drivers/net/wireless/ath/ath6kl/wmi.c | |
parent | b4b2a0b116d79510640622a5f28f219065e61b03 (diff) |
ath6kl: Fix lockdep warning
The following is the lockdep warning which detects possible
deadlock condition with the way ar->lock and ar->list_lock
are being used.
(&(&ar->lock)->rlock){+.-...}, at: [<ffffffffa0492d13>] ath6kl_indicate_tx_activity+0x83/0x110 [ath6kl]
but this lock took another, SOFTIRQ-unsafe lock in the past:
(&(&ar->list_lock)->rlock){+.+...}
and interrupts could create inverse lock ordering between them.
other info that might help us debug this:
Possible interrupt unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&(&ar->list_lock)->rlock);
local_irq_disable();
lock(&(&ar->lock)->rlock);
lock(&(&ar->list_lock)->rlock);
<Interrupt>
lock(&(&ar->lock)->rlock);
*** DEADLOCK ***
softirqs have to be disabled when acquiring ar->list_lock to avoid
the above deadlock condition. When the above warning printed the
interface is still up and running without issue.
Reported-by: Kalle Valo <kvalo@qca.qualcomm.com>
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/wmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index d3db5b3c40bc..ece67a5c37b3 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -89,14 +89,14 @@ struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx) | |||
89 | return NULL; | 89 | return NULL; |
90 | 90 | ||
91 | /* FIXME: Locking */ | 91 | /* FIXME: Locking */ |
92 | spin_lock(&ar->list_lock); | 92 | spin_lock_bh(&ar->list_lock); |
93 | list_for_each_entry(vif, &ar->vif_list, list) { | 93 | list_for_each_entry(vif, &ar->vif_list, list) { |
94 | if (vif->fw_vif_idx == if_idx) { | 94 | if (vif->fw_vif_idx == if_idx) { |
95 | found = vif; | 95 | found = vif; |
96 | break; | 96 | break; |
97 | } | 97 | } |
98 | } | 98 | } |
99 | spin_unlock(&ar->list_lock); | 99 | spin_unlock_bh(&ar->list_lock); |
100 | 100 | ||
101 | return found; | 101 | return found; |
102 | } | 102 | } |