diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-11-09 06:14:16 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-09 14:35:56 -0500 |
commit | 0ecfe806f146e0cb10c2c5abbb3bb4e91959e41a (patch) | |
tree | e70bd8430b61545e91aacc298718634ac217491f /net/mac80211 | |
parent | d929bbc63069396e723a180cde9cb71adc9f76ac (diff) |
mac80211: fix race between connection monitor & suspend
When the connection monitor timer fires right before
suspend, the following will happen:
timer fires -> monitor_work gets queued
suspend calls ieee80211_sta_quiesce
ieee80211_sta_quiesce:
- deletes timer
- cancels monitor_work synchronously, running it
[note wrong order of these steps]
monitor_work runs, re-arming the timer
later, timer fires while system should be quiesced
This causes a warning:
WARNING: at net/mac80211/util.c:540 ieee80211_can_queue_work+0x35/0x40 [mac80211]()
but is otherwise harmless. I'm not completely sure
this is the scenario Thomas stumbled across, but it
is the only way I can right now see the warning in
a scenario like the one he reported.
Reported-by: Thomas Meyer <thomas@m3y3r.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/mlme.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d3b408cda08d..40db011da580 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2286,6 +2286,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
2286 | 2286 | ||
2287 | cancel_work_sync(&ifmgd->request_smps_work); | 2287 | cancel_work_sync(&ifmgd->request_smps_work); |
2288 | 2288 | ||
2289 | cancel_work_sync(&ifmgd->monitor_work); | ||
2289 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); | 2290 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); |
2290 | if (del_timer_sync(&ifmgd->timer)) | 2291 | if (del_timer_sync(&ifmgd->timer)) |
2291 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 2292 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
@@ -2294,7 +2295,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
2294 | if (del_timer_sync(&ifmgd->chswitch_timer)) | 2295 | if (del_timer_sync(&ifmgd->chswitch_timer)) |
2295 | set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); | 2296 | set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); |
2296 | 2297 | ||
2297 | cancel_work_sync(&ifmgd->monitor_work); | ||
2298 | /* these will just be re-established on connection */ | 2298 | /* these will just be re-established on connection */ |
2299 | del_timer_sync(&ifmgd->conn_mon_timer); | 2299 | del_timer_sync(&ifmgd->conn_mon_timer); |
2300 | del_timer_sync(&ifmgd->bcn_mon_timer); | 2300 | del_timer_sync(&ifmgd->bcn_mon_timer); |