mac80211: use freezable workqueue for restart work
authorEliad Peller <eliad@wizery.com>
Sun, 25 Oct 2015 08:59:35 +0000 (10:59 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 3 Nov 2015 09:41:01 +0000 (10:41 +0100)
Requesting hw restart during suspend might result
in the restart work being executed after mac80211
and the hw are suspended.

Solve the race by simply scheduling the restart
work on a freezable workqueue.

Note that there can be some cases of reconfiguration
on resume (besides the hardware restart):

* wowlan is not configured -
    All the interfaces removed were removed on suspend,
    and drv_stop() was called. At this point the driver
    shouldn't expect for hw_restart anyway, so we can
    simply cancel it (on resume).

* wowlan is configured, drv_resume() == 1
    There is no definitive expected behavior in this case,
    as each driver might have different expectations (e.g.
    setting some flags on suspend/restart vs. not handling
    spurious recovery).
    For now, simply let the hw_restart work run again after
    resume, and hope the driver will handle it well (or at
    least initiate another hw restart).

Signed-off-by: Eliad Peller <eliadx.peller@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/main.c
net/mac80211/util.c

index 273c96de4910970a0db3cd95c0da75d3a1695c9d..858f6b1cb1494702bbc6e0d8d25f1b4d4b4d1470 100644 (file)
@@ -281,7 +281,7 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
        local->in_reconfig = true;
        barrier();
 
-       schedule_work(&local->restart_work);
+       queue_work(system_freezable_wq, &local->restart_work);
 }
 EXPORT_SYMBOL(ieee80211_restart_hw);
 
index c5ed42f2f667c8410337b5660d3c5a2ece8b1e8f..7f7ddc527baab0c36c67cb4bc87c10a8aa3e0e39 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
  * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
+ * Copyright (C) 2015  Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -1753,6 +1754,16 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        }
 #endif
 
+       /*
+        * In case of hw_restart during suspend (without wowlan),
+        * cancel restart work, as we are reconfiguring the device
+        * anyway.
+        * Note that restart_work is scheduled on a frozen workqueue,
+        * so we can't deadlock in this case.
+        */
+       if (suspended && local->in_reconfig && !reconfig_due_to_wowlan)
+               cancel_work_sync(&local->restart_work);
+
        /*
         * Upon resume hardware can sometimes be goofy due to
         * various platform / driver / bus issues, so restarting