diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-07-30 07:30:46 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-04 15:27:36 -0400 |
commit | 02f5ba5bac8b374bc2126920c7204c63019f28ce (patch) | |
tree | 47f498455ce5b765ca7253dc3e78b60cd47de394 /drivers | |
parent | 3ff1c25927e3af61c6bf0e4ed959504058ae4565 (diff) |
iwlwifi: fix possible recursive locking deadlock
commit f84b29ec0a1ab767679d3f2428877b65f94bc3ff
Author: Johannes Berg <johannes.berg@intel.com>
Date: Tue May 18 02:29:13 2010 -0700
iwlwifi: queue user-initiated scan when doing internal scan
introduced a potential deadlock because it calls
ieee80211_scan_completed() with the priv->mutex
held, but mac80211 may call back into iwlwifi
which would lead to recursive locking. Move this
out from under the mutex.
Cc: stable@kernel.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8024d44ce4bb..8ccb6d205b6d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -2000,6 +2000,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, | |||
2000 | struct ieee80211_vif *vif) | 2000 | struct ieee80211_vif *vif) |
2001 | { | 2001 | { |
2002 | struct iwl_priv *priv = hw->priv; | 2002 | struct iwl_priv *priv = hw->priv; |
2003 | bool scan_completed = false; | ||
2003 | 2004 | ||
2004 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 2005 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
2005 | 2006 | ||
@@ -2013,7 +2014,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, | |||
2013 | if (priv->vif == vif) { | 2014 | if (priv->vif == vif) { |
2014 | priv->vif = NULL; | 2015 | priv->vif = NULL; |
2015 | if (priv->scan_vif == vif) { | 2016 | if (priv->scan_vif == vif) { |
2016 | ieee80211_scan_completed(priv->hw, true); | 2017 | scan_completed = true; |
2017 | priv->scan_vif = NULL; | 2018 | priv->scan_vif = NULL; |
2018 | priv->scan_request = NULL; | 2019 | priv->scan_request = NULL; |
2019 | } | 2020 | } |
@@ -2021,6 +2022,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, | |||
2021 | } | 2022 | } |
2022 | mutex_unlock(&priv->mutex); | 2023 | mutex_unlock(&priv->mutex); |
2023 | 2024 | ||
2025 | if (scan_completed) | ||
2026 | ieee80211_scan_completed(priv->hw, true); | ||
2027 | |||
2024 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2028 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2025 | 2029 | ||
2026 | } | 2030 | } |