Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

mac80211: use freezable workqueue for restart work

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.

Signed-off-by: Eliad Peller <eliad@wizery.com>
  • Loading branch information...
commit e7c9c05bc0b564985089aaec8175fb793b473702 1 parent 6e1827d
@elp elp authored
Showing with 12 additions and 1 deletion.
  1. +1 −0  net/mac80211/ieee80211_i.h
  2. +11 −1 net/mac80211/main.c
View
1  net/mac80211/ieee80211_i.h
@@ -854,6 +854,7 @@ struct ieee80211_local {
* via ieee80211_queue_work()
*/
struct workqueue_struct *workqueue;
+ struct workqueue_struct *freezable_workqueue;
unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
/* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
View
12 net/mac80211/main.c
@@ -402,7 +402,7 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
local->in_reconfig = true;
barrier();
- schedule_work(&local->restart_work);
+ queue_work(local->freezable_workqueue, &local->restart_work);
}
EXPORT_SYMBOL(ieee80211_restart_hw);
@@ -956,6 +956,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
goto fail_workqueue;
}
+ local->freezable_workqueue =
+ create_freezable_workqueue(wiphy_name(local->hw.wiphy));
+ if (!local->freezable_workqueue) {
+ result = -ENOMEM;
+ goto fail_freezable;
+ }
+
/*
* The hardware needs headroom for sending the frame,
* and we need some headroom for passing the frame to monitor
@@ -1039,6 +1046,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
rtnl_unlock();
ieee80211_wep_free(local);
sta_info_stop(local);
+ destroy_workqueue(local->freezable_workqueue);
+ fail_freezable:
destroy_workqueue(local->workqueue);
fail_workqueue:
wiphy_unregister(local->hw.wiphy);
@@ -1088,6 +1097,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
skb_queue_purge(&local->rx_skb_queue);
destroy_workqueue(local->workqueue);
+ destroy_workqueue(local->freezable_workqueue);
wiphy_unregister(local->hw.wiphy);
sta_info_stop(local);
ieee80211_wep_free(local);
Please sign in to comment.
Something went wrong with that request. Please try again.