wifi: mac80211: move sched-scan stop work to wiphy work
authorJohannes Berg <johannes.berg@intel.com>
Mon, 28 Aug 2023 11:59:45 +0000 (13:59 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 20 Nov 2023 10:51:51 +0000 (11:51 +0100)
[ Upstream commit eadfb54756aea5610d8d0a467f66305f777c85dd ]

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: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver")
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/mac80211/ieee80211_i.h
net/mac80211/main.c
net/mac80211/scan.c

index 2bf63908a35e9c2a88fef937a7430ffb86fe94bc..d5dd2d9e89b489745ca3a195ab65db0dc354a055 100644 (file)
@@ -1438,7 +1438,7 @@ struct ieee80211_local {
        int hw_scan_ies_bufsize;
        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 cfg80211_sched_scan_request __rcu *sched_scan_req;
        u8 scan_addr[ETH_ALEN];
@@ -1892,7 +1892,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
                                       struct cfg80211_sched_scan_request *req);
 int ieee80211_request_sched_scan_stop(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 */
 void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local);
index 71c1b4603623e72bb170e2f11cbf79437036ef9b..6faba47b7b0ea1532a2f6400a17911871aa45f30 100644 (file)
@@ -820,8 +820,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
                  ieee80211_dynamic_ps_disable_work);
        timer_setup(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer, 0);
 
-       INIT_WORK(&local->sched_scan_stopped_work,
-                 ieee80211_sched_scan_stopped_work);
+       wiphy_work_init(&local->sched_scan_stopped_work,
+                       ieee80211_sched_scan_stopped_work);
 
        spin_lock_init(&local->ack_status_lock);
        idr_init(&local->ack_status_frames);
@@ -1470,13 +1470,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 
        wiphy_lock(local->hw.wiphy);
        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_unlock(local->hw.wiphy);
        rtnl_unlock();
 
        cancel_work_sync(&local->restart_work);
        cancel_work_sync(&local->reconfig_filter);
-       flush_work(&local->sched_scan_stopped_work);
 
        ieee80211_clear_tx_pending(local);
        rate_control_deinitialize(local);
index 445b789e0e9bf7c2cd306226084451ec9a115aae..c37e2576f1c1305c0f7130959d8c99e223632758 100644 (file)
@@ -1439,10 +1439,11 @@ void ieee80211_sched_scan_end(struct ieee80211_local *local)
 
        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 =
                container_of(work, struct ieee80211_local,
@@ -1465,6 +1466,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
        if (local->in_reconfig)
                return;
 
-       schedule_work(&local->sched_scan_stopped_work);
+       wiphy_work_queue(hw->wiphy, &local->sched_scan_stopped_work);
 }
 EXPORT_SYMBOL(ieee80211_sched_scan_stopped);