aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2015-01-22 15:39:59 +0200
committerLuciano Coelho <luciano.coelho@intel.com>2015-01-23 16:57:51 +0200
commit9ffe17687f281f9d3242c237682d2db2fb5103c4 (patch)
tree4b2c67541025560ff43a2ec84addcfbfc006f4f9
parent20cd41d492576a35a70c080a459c47a8c3838bef (diff)
downloadchromiumos-intel-chromiumos-3.10.tar.gz
CHROMIUM: mac80211: handle potential race between suspend and scan completionchromiumos-3.10
If suspend starts while ieee80211_scan_completed() is running, between the point where SCAN_COMPLETED is set and the work is queued, ieee80211_scan_cancel() will not catch the work and we may finish suspending before the work is actually executed, leaving the scan running while suspended. To fix this race, queue the scan work during resume if the SCAN_COMPLETED flag is set and flush it immediately. Change-Id: I1149d2202746a748d8f178d909d738a4411525bd Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
-rw-r--r--drivers/net/wireless-3.8/iwl7000/mac80211/ieee80211_i.h3
-rw-r--r--drivers/net/wireless-3.8/iwl7000/mac80211/util.c12
2 files changed, 14 insertions, 1 deletions
diff --git a/drivers/net/wireless-3.8/iwl7000/mac80211/ieee80211_i.h b/drivers/net/wireless-3.8/iwl7000/mac80211/ieee80211_i.h
index b5e248e2f0aa4f..21dfb5ef817a91 100644
--- a/drivers/net/wireless-3.8/iwl7000/mac80211/ieee80211_i.h
+++ b/drivers/net/wireless-3.8/iwl7000/mac80211/ieee80211_i.h
@@ -1698,7 +1698,8 @@ static inline int __ieee80211_resume(struct ieee80211_hw *hw)
{
struct ieee80211_local *local = hw_to_local(hw);
- WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
+ WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) &&
+ !test_bit(SCAN_COMPLETED, &local->scanning),
"%s: resume with hardware scan still in progress\n",
wiphy_name(hw->wiphy));
diff --git a/drivers/net/wireless-3.8/iwl7000/mac80211/util.c b/drivers/net/wireless-3.8/iwl7000/mac80211/util.c
index af2e77ed7a6ddb..c1c14e6956e907 100644
--- a/drivers/net/wireless-3.8/iwl7000/mac80211/util.c
+++ b/drivers/net/wireless-3.8/iwl7000/mac80211/util.c
@@ -1938,6 +1938,18 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mb();
local->resuming = false;
+ /* It's possible that we don't handle the scan completion in
+ * time during suspend, so if it's still marked as completed
+ * here, queue the work and flush it to clean things up.
+ * Instead of calling the worker function directly here, we
+ * really queue it to avoid potential races with other flows
+ * scheduling the same work.
+ */
+ if (test_bit(SCAN_COMPLETED, &local->scanning)) {
+ ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
+ flush_delayed_work(&local->scan_work);
+ }
+
list_for_each_entry(sdata, &local->interfaces, list) {
if (!ieee80211_sdata_running(sdata))
continue;