some scan patches
Subsystems (2)
Johannes Berg
maintainercover some scan patches
Been wanting to do this for a while,
mostly for code complexity reasons.
johannes
Johannes Berg
maintainerPATCH 1/3 mac80211: remove unused scan expire define
From: Johannes Berg <[email protected]>
Since cfg80211 manages the BSS list completely,
this define hasn't been used for a long time
and will never be used again.
--- net/mac80211/ieee80211_i.h | 6 ------ 1 file changed, 6 deletions(-)
net/mac80211/ieee80211_i.h +0 -6
@@ -50,12 +50,6 @@ struct ieee80211_local;* increased memory use (about 2 kB of RAM per entry). */ #define IEEE80211_FRAGMENT_MAX 4 -/* -* Time after which we ignore scan results and no longer report/use -* them in any way. -*/ -#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) -#define TU_TO_EXP_TIME (x) (jiffies + usecs_to_jiffies((x) * 1024))#define IEEE80211_DEFAULT_UAPSD_QUEUES \
Johannes Berg
maintainerPATCH 2/3 mac80211: allow scan to complete from any context
In reply to Johannes BergFrom: Johannes Berg <[email protected]>
The ieee80211_scan_completed() function was a frequent source of potential deadlocks, since it is called by drivers but may call back into drivers, so drivers had to make sure to call it without any locks held, which frequently lead to more complex code in drivers. Avoid that problem by allowing the function to be called in any context, and queueing the actual work it does. Also update the documentation for it to indicate this.
--- include/net/mac80211.h | 3 ++- net/mac80211/ieee80211_i.h | 6 ++++++ net/mac80211/scan.c | 34 ++++++++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 9 deletions(-)
net/mac80211/scan.c +26 -8
@@ -249,13 +249,11 @@ static bool ieee80211_prep_hw_scan(strucreturn true; } -void ieee80211_scan_completed (struct ieee80211_hw *hw,bool aborted) +static void __ieee80211_scan_completed (struct ieee80211_hw *hw,bool aborted) {struct ieee80211_local *local =hw_to_local (hw);bool was_hw_scan; -trace_api_scan_completed (local, aborted); -mutex_lock (&local->mtx);/*
@@ -313,6 +311,18 @@ void ieee80211_scan_completed(struct ieeieee80211_mesh_notify_scan_completed (local);ieee80211_queue_work (&local->hw, &local->work_work); } + +void ieee80211_scan_completed (struct ieee80211_hw *hw,bool aborted) +{ +struct ieee80211_local *local =hw_to_local (hw); + +trace_api_scan_completed (local, aborted); + +set_bit (SCAN_COMPLETED , &local->scanning); +if (aborted) +set_bit (SCAN_ABORTED , &local->scanning); +ieee80211_queue_delayed_work (&local->hw, &local->scan_work,0 ); +}EXPORT_SYMBOL (ieee80211_scan_completed);static int ieee80211_start_sw_scan (struct ieee80211_local *local)
@@ -450,7 +460,7 @@ static int ieee80211_scan_state_decision/* if no more bands/channels left, complete scan and advance to the idle state */ if (local->scan_channel_idx >= local->scan_req->n_channels) { -ieee80211_scan_completed (&local->hw, false); +__ieee80211_scan_completed (&local->hw, false);return 1 ; }
@@ -642,6 +652,14 @@ void ieee80211_scan_work(struct work_strstruct ieee80211_sub_if_data *sdata = local->scan_sdata;unsigned long next_delay =0 ; +if (test_and_clear_bit (SCAN_COMPLETED , &local->scanning)) { +bool aborted; + + aborted =test_and_clear_bit (SCAN_ABORTED , &local->scanning); +__ieee80211_scan_completed (&local->hw, aborted); +return ; + } +mutex_lock (&local->mtx);if (!sdata || !local->scan_req) {mutex_unlock (&local->mtx);
@@ -652,7 +670,7 @@ void ieee80211_scan_work(struct work_strint rc =drv_hw_scan (local, sdata, local->hw_scan_req);mutex_unlock (&local->mtx);if (rc) -ieee80211_scan_completed (&local->hw, true); +__ieee80211_scan_completed (&local->hw, true);return ; }
@@ -667,7 +685,7 @@ void ieee80211_scan_work(struct work_strmutex_unlock (&local->mtx);if (rc) -ieee80211_scan_completed (&local->hw, true); +__ieee80211_scan_completed (&local->hw, true);return ; }
@@ -677,7 +695,7 @@ void ieee80211_scan_work(struct work_str* Avoid re-scheduling when the sdata is going away. */ if (!ieee80211_sdata_running (sdata)) { -ieee80211_scan_completed (&local->hw, true); +__ieee80211_scan_completed (&local->hw, true);return ; }
@@ -784,5 +802,5 @@ void ieee80211_scan_cancel(struct ieee80mutex_unlock (&local->mtx);if (abortscan) -ieee80211_scan_completed (&local->hw, true); +__ieee80211_scan_completed (&local->hw, true); }
net/mac80211/ieee80211_i.h +6 -0
@@ -596,11 +596,17 @@ enum queue_stop_reason {* determine if we are on the operating channel or not * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, * gets only set in conjunction with SCAN_SW_SCANNING +* @SCAN_COMPLETED: Set for our scan work function when the driver reported +* that the scan completed. +* @SCAN_ABORTED: Set for our scan work function when the driver reported +* a scan complete for an aborted scan. */ enum {SCAN_SW_SCANNING ,SCAN_HW_SCANNING ,SCAN_OFF_CHANNEL , +SCAN_COMPLETED , +SCAN_ABORTED , };/**
include/net/mac80211.h +2 -1
@@ -2268,7 +2268,8 @@ void ieee80211_wake_queues(struct ieee80* * When hardware scan offload is used (i.e. the hw_scan() callback is * assigned) this function needs to be called by the driver to notify -* mac80211 that the scan finished. +* mac80211 that the scan finished. This function can be called from +* any context, including hardirq context. * * @hw: the hardware that finished the scan * @aborted: set to true if scan was aborted
Johannes Berg
maintainerPATCH 3/3 wl12xx: remove unneeded locking
In reply to Johannes BergFrom: Johannes Berg <[email protected]>
With the scan callback now being callable from any context, these unlocks/locks can go away. This makes the code easier to understand, since callers of these functions must no longer be aware that the mutex may be dropped.
As Stanislaw is working on iwlwifi scanning, I didn't change it to take advantage of the new mac80211 semantics.
--- drivers/net/wireless/wl12xx/wl1251_event.c | 2 -- drivers/net/wireless/wl12xx/wl1251_main.c | 2 -- drivers/net/wireless/wl12xx/wl1271_main.c | 2 -- drivers/net/wireless/wl12xx/wl1271_scan.c | 2 -- 4 files changed, 8 deletions(-)
drivers/net/wireless/wl12xx/wl1251_event.c +0 -2
@@ -36,9 +36,7 @@ static int wl1251_event_scan_complete(st mbox->scheduled_scan_channels);if (wl->scanning) { -mutex_unlock (&wl->mutex);ieee80211_scan_completed (wl->hw, false); -mutex_lock (&wl->mutex);wl1251_debug (DEBUG_MAC80211 ,"mac80211 hw scan completed" ); wl->scanning = false; }
drivers/net/wireless/wl12xx/wl1251_main.c +0 -2
@@ -469,9 +469,7 @@ static void wl1251_op_stop(struct ieee80WARN_ON (wl->state !=WL1251_STATE_ON );if (wl->scanning) { -mutex_unlock (&wl->mutex);ieee80211_scan_completed (wl->hw, true); -mutex_lock (&wl->mutex); wl->scanning = false; }
drivers/net/wireless/wl12xx/wl1271_main.c +0 -2
@@ -948,9 +948,7 @@ static void wl1271_op_remove_interface(sieee80211_enable_dyn_ps (wl->vif);if (wl->scan.state !=WL1271_SCAN_STATE_IDLE ) { -mutex_unlock (&wl->mutex);ieee80211_scan_completed (wl->hw, true); -mutex_lock (&wl->mutex); wl->scan.state =WL1271_SCAN_STATE_IDLE ;kfree (wl->scan.scanned_ch); wl->scan.scanned_ch =NULL ;
drivers/net/wireless/wl12xx/wl1271_scan.c +0 -2
@@ -215,9 +215,7 @@ void wl1271_scan_stm(struct wl1271 *wl)break ;case WL1271_SCAN_STATE_DONE : -mutex_unlock (&wl->mutex);ieee80211_scan_completed (wl->hw, false); -mutex_lock (&wl->mutex);kfree (wl->scan.scanned_ch); wl->scan.scanned_ch =NULL ;
Re: [PATCH 3/3] wl12xx: remove unneeded locking
Quoted 8 lines · Johannes Berg
From: Johannes Berg <[email protected]>
With the scan callback now being callable from any context, these unlocks/locks can go away. This makes the code easier to understand, since callers of these functions must no longer be aware that the mutex may be dropped.
Quoted 8 lines
As Stanislaw is working on iwlwifi scanning, I didn't change it to take advantage of the new mac80211 semantics.
Signed-off-by Johannes Berg <[email protected]>--- drivers/net/wireless/wl12xx/wl1251_event.c | 2 -- drivers/net/wireless/wl12xx/wl1251_main.c | 2 --
Thanks, wl1251 part looks good. I didn't test them yet, but will do soon.
Signature · 1 line
Kalle Valo
Re: [PATCH 3/3] wl12xx: remove unneeded locking
In reply to Johannes BergQuoted 14 lines · ext Johannes Berg
From: Johannes Berg <[email protected]>
With the scan callback now being callable from any context, these unlocks/locks can go away. This makes the code easier to understand, since callers of these functions must no longer be aware that the mutex may be dropped.
As Stanislaw is working on iwlwifi scanning, I didn't change it to take advantage of the new mac80211 semantics.
Signed-off-by Johannes Berg <[email protected]>---
[...]
Quoted 15 lines
drivers/net/wireless/wl12xx/wl1271_main.c +0
-2@@ -948,9 +948,7 @@ static void wl1271_op_remove_interface(sieee80211_enable_dyn_ps (wl->vif);if (wl->scan.state !=WL1271_SCAN_STATE_IDLE ) { -mutex_unlock (&wl->mutex);ieee80211_scan_completed (wl->hw, true); -mutex_lock (&wl->mutex); wl->scan.state =WL1271_SCAN_STATE_IDLE ;kfree (wl->scan.scanned_ch); wl->scan.scanned_ch =NULL ;
drivers/net/wireless/wl12xx/wl1271_scan.c void wl1271_scan_stm(struct wl1271 *wl) · line 221
Quoted 9 lines
drivers/net/wireless/wl12xx/wl1271_scan.c +0
-2@@ -215,9 +215,7 @@ void wl1271_scan_stm(struct wl1271 *wl)break ;case WL1271_SCAN_STATE_DONE : -mutex_unlock (&wl->mutex);ieee80211_scan_completed (wl->hw, false); -mutex_lock (&wl->mutex);kfree (wl->scan.scanned_ch); wl->scan.scanned_ch =NULL ;
Yes, the wl1271 part also looks good. This definitely simplifies things and makes the code more robust.
Signature · 2 lines
Cheers, Luca.