Message ID | 1422088202-31871-1-git-send-email-luca@coelho.fi (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Johannes Berg |
Headers | show |
On Sat, 2015-01-24 at 10:30 +0200, Luca Coelho wrote: > From: Luciano Coelho <luciano.coelho@intel.com> > > 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. Applied. I've put it into mac80211-next, we can look later if we should send it to various stable trees. johannes -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index bdb3e3b..3afe368 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1752,7 +1752,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/net/mac80211/util.c b/net/mac80211/util.c index c65d03f..8428f4a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2060,6 +2060,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); + } + if (local->open_count && !reconfig_due_to_wowlan) drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND);