summaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2015-01-24 03:30:02 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-01-27 03:58:46 -0500
commit9120d94e8f9abd3eb9f00a5aaa6eca85cdf4f439 (patch)
treeb141172aa32ce2fa5f9a531efae302f5c04ac112 /net/mac80211/util.c
parent225b818982403120ce1f5e7d4b3e5245e0399775 (diff)
mac80211: handle potential race between suspend and scan completion
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. Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index c65d03f3c167..8428f4a95479 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2060,6 +2060,18 @@ int ieee80211_reconfig(struct ieee80211_local *local)
2060 mb(); 2060 mb();
2061 local->resuming = false; 2061 local->resuming = false;
2062 2062
2063 /* It's possible that we don't handle the scan completion in
2064 * time during suspend, so if it's still marked as completed
2065 * here, queue the work and flush it to clean things up.
2066 * Instead of calling the worker function directly here, we
2067 * really queue it to avoid potential races with other flows
2068 * scheduling the same work.
2069 */
2070 if (test_bit(SCAN_COMPLETED, &local->scanning)) {
2071 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
2072 flush_delayed_work(&local->scan_work);
2073 }
2074
2063 if (local->open_count && !reconfig_due_to_wowlan) 2075 if (local->open_count && !reconfig_due_to_wowlan)
2064 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); 2076 drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);
2065 2077