|
@@ -255,8 +255,27 @@ static void ieee80211_restart_work(struct work_struct *work)
|
|
|
|
|
|
flush_work(&local->radar_detected_work);
|
|
flush_work(&local->radar_detected_work);
|
|
rtnl_lock();
|
|
rtnl_lock();
|
|
- list_for_each_entry(sdata, &local->interfaces, list)
|
|
|
|
|
|
+ list_for_each_entry(sdata, &local->interfaces, list) {
|
|
|
|
+ /*
|
|
|
|
+ * XXX: there may be more work for other vif types and even
|
|
|
|
+ * for station mode: a good thing would be to run most of
|
|
|
|
+ * the iface type's dependent _stop (ieee80211_mg_stop,
|
|
|
|
+ * ieee80211_ibss_stop) etc...
|
|
|
|
+ * For now, fix only the specific bug that was seen: race
|
|
|
|
+ * between csa_connection_drop_work and us.
|
|
|
|
+ */
|
|
|
|
+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
|
|
|
|
+ /*
|
|
|
|
+ * This worker is scheduled from the iface worker that
|
|
|
|
+ * runs on mac80211's workqueue, so we can't be
|
|
|
|
+ * scheduling this worker after the cancel right here.
|
|
|
|
+ * The exception is ieee80211_chswitch_done.
|
|
|
|
+ * Then we can have a race...
|
|
|
|
+ */
|
|
|
|
+ cancel_work_sync(&sdata->u.mgd.csa_connection_drop_work);
|
|
|
|
+ }
|
|
flush_delayed_work(&sdata->dec_tailroom_needed_wk);
|
|
flush_delayed_work(&sdata->dec_tailroom_needed_wk);
|
|
|
|
+ }
|
|
ieee80211_scan_cancel(local);
|
|
ieee80211_scan_cancel(local);
|
|
|
|
|
|
/* make sure any new ROC will consider local->in_reconfig */
|
|
/* make sure any new ROC will consider local->in_reconfig */
|