From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
To: linville@tuxdriver.com
Cc: linux-wireless@vger.kernel.org,
Johannes Berg <johannes.berg@intel.com>,
Wey-Yi Guy <wey-yi.w.guy@intel.com>
Subject: [PATCH 12/12] iwlagn: fix scan complete processing
Date: Thu, 22 Sep 2011 15:15:00 -0700 [thread overview]
Message-ID: <1316729700-1770-13-git-send-email-wey-yi.w.guy@intel.com> (raw)
In-Reply-To: <1316729700-1770-1-git-send-email-wey-yi.w.guy@intel.com>
From: Johannes Berg <johannes.berg@intel.com>
When we cancel a scan, the completion runs
only from the workqueue. This can cause the
remain-on-channel scan to fail when another
one was just canceled, because we're still
aborting it.
To fix this, run the completion inline with
the lock still held before returning from
iwl_scan_cancel_timeout().
Also, to avoid the scan complete work from
completing a new scan prematurely, add a
new STATUS_SCAN_COMPLETE bit.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Tested-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-scan.c | 36 +++++++++++++++++++++++++---
drivers/net/wireless/iwlwifi/iwl-shared.h | 1 +
2 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index e50338b..c5c95d5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -118,6 +118,11 @@ static void iwl_process_scan_complete(struct iwl_priv *priv)
{
bool aborted;
+ lockdep_assert_held(&priv->shrd->mutex);
+
+ if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status))
+ return;
+
IWL_DEBUG_SCAN(priv, "Completed scan.\n");
cancel_delayed_work(&priv->scan_check);
@@ -181,6 +186,7 @@ void iwl_force_scan_end(struct iwl_priv *priv)
clear_bit(STATUS_SCANNING, &priv->shrd->status);
clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status);
+ clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
iwl_complete_scan(priv, true);
}
@@ -235,9 +241,24 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
while (time_before_eq(jiffies, timeout)) {
if (!test_bit(STATUS_SCAN_HW, &priv->shrd->status))
- break;
+ goto finished;
msleep(20);
}
+
+ return;
+
+ finished:
+ /*
+ * Now STATUS_SCAN_HW is clear. This means that the
+ * device finished, but the background work is going
+ * to execute at best as soon as we release the mutex.
+ * Since we need to be able to issue a new scan right
+ * after this function returns, run the complete here.
+ * The STATUS_SCAN_COMPLETE bit will then be cleared
+ * and prevent the background work from "completing"
+ * a possible new scan.
+ */
+ iwl_process_scan_complete(priv);
}
/* Service response to REPLY_SCAN_CMD (0x80) */
@@ -321,13 +342,20 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
scan_notif->tsf_low,
scan_notif->tsf_high, scan_notif->status);
- /* The HW is no longer scanning */
- clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
-
IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
(priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
jiffies_to_msecs(jiffies - priv->scan_start));
+ /*
+ * When aborting, we run the scan completed background work inline
+ * and the background work must then do nothing. The SCAN_COMPLETE
+ * bit helps implement that logic and thus needs to be set before
+ * queueing the work. Also, since the scan abort waits for SCAN_HW
+ * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW
+ * to avoid a race there.
+ */
+ set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
+ clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
queue_work(priv->shrd->workqueue, &priv->scan_completed);
if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h
index 7abafe1..8747bbd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -489,6 +489,7 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
#define STATUS_FW_ERROR 17
#define STATUS_DEVICE_ENABLED 18
#define STATUS_CHANNEL_SWITCH_PENDING 19
+#define STATUS_SCAN_COMPLETE 20
static inline int iwl_is_ready(struct iwl_shared *shrd)
{
--
1.7.0.4
prev parent reply other threads:[~2011-09-22 23:01 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-22 22:14 [PATCH 00/12] update for 3.2 Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 01/12] MAINTAINERS: update iwlwifi Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 02/12] iwlagn: set the sequence control from the transport layer Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 03/12] iwlagn: add debugging to show probe related info in scan notification Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 04/12] iwlagn: update rate scaling with BA notifications Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 05/12] iwlagn: use kcalloc when possible for array allocation Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 06/12] iwlagn: fix dangling scan request Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 07/12] iwlagn: fix slot programming Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 08/12] iwlagn: remove Kelvin support Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 09/12] iwlagn: make iwl_scan_cancel_timeout void Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 10/12] iwlagn: refactor scan complete Wey-Yi Guy
2011-09-22 22:14 ` [PATCH 11/12] iwlagn: move iwl_process_scan_complete up Wey-Yi Guy
2011-09-22 22:15 ` Wey-Yi Guy [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1316729700-1770-13-git-send-email-wey-yi.w.guy@intel.com \
--to=wey-yi.w.guy@intel.com \
--cc=johannes.berg@intel.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox