Commit eadfb547 authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: move sched-scan stop work to wiphy work

This also has the wiphy locked here then. We need to use
the _locked version of cfg80211_sched_scan_stopped() now,
which also fixes an old deadlock there.

Fixes: a05829a7 ("cfg80211: avoid holding the RTNL when calling the driver")
Reviewed-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9fa659f9
...@@ -1489,7 +1489,7 @@ struct ieee80211_local { ...@@ -1489,7 +1489,7 @@ struct ieee80211_local {
int hw_scan_ies_bufsize; int hw_scan_ies_bufsize;
struct cfg80211_scan_info scan_info; struct cfg80211_scan_info scan_info;
struct work_struct sched_scan_stopped_work; struct wiphy_work sched_scan_stopped_work;
struct ieee80211_sub_if_data __rcu *sched_scan_sdata; struct ieee80211_sub_if_data __rcu *sched_scan_sdata;
struct cfg80211_sched_scan_request __rcu *sched_scan_req; struct cfg80211_sched_scan_request __rcu *sched_scan_req;
u8 scan_addr[ETH_ALEN]; u8 scan_addr[ETH_ALEN];
...@@ -1968,7 +1968,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, ...@@ -1968,7 +1968,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
struct cfg80211_sched_scan_request *req); struct cfg80211_sched_scan_request *req);
int ieee80211_request_sched_scan_stop(struct ieee80211_local *local); int ieee80211_request_sched_scan_stop(struct ieee80211_local *local);
void ieee80211_sched_scan_end(struct ieee80211_local *local); void ieee80211_sched_scan_end(struct ieee80211_local *local);
void ieee80211_sched_scan_stopped_work(struct work_struct *work); void ieee80211_sched_scan_stopped_work(struct wiphy *wiphy,
struct wiphy_work *work);
/* off-channel/mgmt-tx */ /* off-channel/mgmt-tx */
void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local); void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local);
......
...@@ -843,8 +843,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, ...@@ -843,8 +843,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
ieee80211_dynamic_ps_disable_work); ieee80211_dynamic_ps_disable_work);
timer_setup(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer, 0); timer_setup(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer, 0);
INIT_WORK(&local->sched_scan_stopped_work, wiphy_work_init(&local->sched_scan_stopped_work,
ieee80211_sched_scan_stopped_work); ieee80211_sched_scan_stopped_work);
spin_lock_init(&local->ack_status_lock); spin_lock_init(&local->ack_status_lock);
idr_init(&local->ack_status_frames); idr_init(&local->ack_status_frames);
...@@ -1502,13 +1502,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) ...@@ -1502,13 +1502,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
wiphy_lock(local->hw.wiphy); wiphy_lock(local->hw.wiphy);
wiphy_delayed_work_cancel(local->hw.wiphy, &local->roc_work); wiphy_delayed_work_cancel(local->hw.wiphy, &local->roc_work);
wiphy_work_cancel(local->hw.wiphy, &local->sched_scan_stopped_work);
wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work); wiphy_work_cancel(local->hw.wiphy, &local->radar_detected_work);
wiphy_unlock(local->hw.wiphy); wiphy_unlock(local->hw.wiphy);
rtnl_unlock(); rtnl_unlock();
cancel_work_sync(&local->restart_work); cancel_work_sync(&local->restart_work);
cancel_work_sync(&local->reconfig_filter); cancel_work_sync(&local->reconfig_filter);
flush_work(&local->sched_scan_stopped_work);
ieee80211_clear_tx_pending(local); ieee80211_clear_tx_pending(local);
rate_control_deinitialize(local); rate_control_deinitialize(local);
......
...@@ -1422,10 +1422,11 @@ void ieee80211_sched_scan_end(struct ieee80211_local *local) ...@@ -1422,10 +1422,11 @@ void ieee80211_sched_scan_end(struct ieee80211_local *local)
mutex_unlock(&local->mtx); mutex_unlock(&local->mtx);
cfg80211_sched_scan_stopped(local->hw.wiphy, 0); cfg80211_sched_scan_stopped_locked(local->hw.wiphy, 0);
} }
void ieee80211_sched_scan_stopped_work(struct work_struct *work) void ieee80211_sched_scan_stopped_work(struct wiphy *wiphy,
struct wiphy_work *work)
{ {
struct ieee80211_local *local = struct ieee80211_local *local =
container_of(work, struct ieee80211_local, container_of(work, struct ieee80211_local,
...@@ -1448,6 +1449,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) ...@@ -1448,6 +1449,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
if (local->in_reconfig) if (local->in_reconfig)
return; return;
schedule_work(&local->sched_scan_stopped_work); wiphy_work_queue(hw->wiphy, &local->sched_scan_stopped_work);
} }
EXPORT_SYMBOL(ieee80211_sched_scan_stopped); EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment