linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jerome Pouiller <Jerome.Pouiller@silabs.com>
To: devel@driverdev.osuosl.org, linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Kalle Valo" <kvalo@codeaurora.org>,
	"David S . Miller" <davem@davemloft.net>,
	"Jérôme Pouiller" <jerome.pouiller@silabs.com>
Subject: [PATCH 05/31] staging: wfx: avoid possible lock-up during scan
Date: Fri, 10 Sep 2021 18:04:38 +0200	[thread overview]
Message-ID: <20210910160504.1794332-6-Jerome.Pouiller@silabs.com> (raw)
In-Reply-To: <20210910160504.1794332-1-Jerome.Pouiller@silabs.com>

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

If the environment is noisy, the device may take time to send scan
requests. Thus, scan requests durations > 5s have already been observed.
During the scan, traffic is neither received, neither sent. From the
user point-of-view, the traffic is frozen for a long time.

This patch reworks the scan processing. It gives to the device a smaller
time budget than previously. However, it does not expect the scan to be
complete and it is able to send another scan request to finish the work.

A big part of the patch aims to avoid an infinite loop if the device
goes crazy.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_rx.c |  3 ++-
 drivers/staging/wfx/scan.c   | 48 ++++++++++++++++++++++--------------
 drivers/staging/wfx/scan.h   |  2 +-
 drivers/staging/wfx/wfx.h    |  1 +
 4 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c
index 9fca7f26372a..a60c4a4ba935 100644
--- a/drivers/staging/wfx/hif_rx.c
+++ b/drivers/staging/wfx/hif_rx.c
@@ -175,13 +175,14 @@ static int hif_scan_complete_indication(struct wfx_dev *wdev,
 					const void *buf)
 {
 	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
+	const struct hif_ind_scan_cmpl *body = buf;
 
 	if (!wvif) {
 		dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__);
 		return -EIO;
 	}
 
-	wfx_scan_complete(wvif);
+	wfx_scan_complete(wvif, body->num_channels_completed);
 
 	return 0;
 }
diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c
index 1e03b130049b..695b06974194 100644
--- a/drivers/staging/wfx/scan.c
+++ b/drivers/staging/wfx/scan.c
@@ -41,7 +41,7 @@ static int update_probe_tmpl(struct wfx_vif *wvif,
 static int send_scan_req(struct wfx_vif *wvif,
 			 struct cfg80211_scan_request *req, int start_idx)
 {
-	int i, ret, timeout;
+	int i, ret;
 	struct ieee80211_channel *ch_start, *ch_cur;
 
 	for (i = start_idx; i < req->n_channels; i++) {
@@ -56,31 +56,31 @@ static int send_scan_req(struct wfx_vif *wvif,
 	wfx_tx_lock_flush(wvif->wdev);
 	wvif->scan_abort = false;
 	reinit_completion(&wvif->scan_complete);
-	ret = hif_scan(wvif, req, start_idx, i - start_idx, &timeout);
+	ret = hif_scan(wvif, req, start_idx, i - start_idx, NULL);
 	if (ret) {
-		ret = -EIO;
-		goto err_scan_start;
+		wfx_tx_unlock(wvif->wdev);
+		return -EIO;
 	}
-	ret = wait_for_completion_timeout(&wvif->scan_complete, timeout);
+	ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ);
 	if (!ret) {
-		dev_notice(wvif->wdev->dev, "scan timeout\n");
 		hif_stop_scan(wvif);
 		ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ);
-		if (!ret)
-			dev_err(wvif->wdev->dev, "scan didn't stop\n");
+		dev_dbg(wvif->wdev->dev, "scan timeout (%d channels done)\n",
+			wvif->scan_nb_chan_done);
+	}
+	if (!ret) {
+		dev_err(wvif->wdev->dev, "scan didn't stop\n");
 		ret = -ETIMEDOUT;
-		goto err_timeout;
-	}
-	if (wvif->scan_abort) {
+	} else if (wvif->scan_abort) {
 		dev_notice(wvif->wdev->dev, "scan abort\n");
 		ret = -ECONNABORTED;
-		goto err_timeout;
+	} else if (wvif->scan_nb_chan_done > i - start_idx) {
+		ret = -EIO;
+	} else {
+		ret = wvif->scan_nb_chan_done;
 	}
-	ret = i - start_idx;
-err_timeout:
 	if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower)
 		hif_set_output_power(wvif, wvif->vif->bss_conf.txpower);
-err_scan_start:
 	wfx_tx_unlock(wvif->wdev);
 	return ret;
 }
@@ -94,7 +94,7 @@ void wfx_hw_scan_work(struct work_struct *work)
 {
 	struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan_work);
 	struct ieee80211_scan_request *hw_req = wvif->scan_req;
-	int chan_cur, ret;
+	int chan_cur, ret, err;
 
 	mutex_lock(&wvif->wdev->conf_mutex);
 	mutex_lock(&wvif->scan_lock);
@@ -105,11 +105,20 @@ void wfx_hw_scan_work(struct work_struct *work)
 	}
 	update_probe_tmpl(wvif, &hw_req->req);
 	chan_cur = 0;
+	err = 0;
 	do {
 		ret = send_scan_req(wvif, &hw_req->req, chan_cur);
-		if (ret > 0)
+		if (ret > 0) {
 			chan_cur += ret;
-	} while (ret > 0 && chan_cur < hw_req->req.n_channels);
+			err = 0;
+		}
+		if (!ret)
+			err++;
+		if (err > 2) {
+			dev_err(wvif->wdev->dev, "scan has not been able to start\n");
+			ret = -ETIMEDOUT;
+		}
+	} while (ret >= 0 && chan_cur < hw_req->req.n_channels);
 	mutex_unlock(&wvif->scan_lock);
 	mutex_unlock(&wvif->wdev->conf_mutex);
 	__ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0);
@@ -134,7 +143,8 @@ void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	hif_stop_scan(wvif);
 }
 
-void wfx_scan_complete(struct wfx_vif *wvif)
+void wfx_scan_complete(struct wfx_vif *wvif, int nb_chan_done)
 {
+	wvif->scan_nb_chan_done = nb_chan_done;
 	complete(&wvif->scan_complete);
 }
diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h
index c7496a766478..562ca1321daf 100644
--- a/drivers/staging/wfx/scan.h
+++ b/drivers/staging/wfx/scan.h
@@ -17,6 +17,6 @@ void wfx_hw_scan_work(struct work_struct *work);
 int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		struct ieee80211_scan_request *req);
 void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
-void wfx_scan_complete(struct wfx_vif *wvif);
+void wfx_scan_complete(struct wfx_vif *wvif, int nb_chan_done);
 
 #endif /* WFX_SCAN_H */
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 94898680ccde..56f1e4bb0b57 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -85,6 +85,7 @@ struct wfx_vif {
 	struct mutex		scan_lock;
 	struct work_struct	scan_work;
 	struct completion	scan_complete;
+	int			scan_nb_chan_done;
 	bool			scan_abort;
 	struct ieee80211_scan_request *scan_req;
 
-- 
2.33.0


  parent reply	other threads:[~2021-09-10 16:05 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-10 16:04 [PATCH 00/31] [PATCH 00/31] staging/wfx: usual maintenance Jerome Pouiller
2021-09-10 16:04 ` [PATCH 01/31] staging: wfx: use abbreviated message for "incorrect sequence" Jerome Pouiller
2021-09-10 16:04 ` [PATCH 02/31] staging: wfx: do not send CAB while scanning Jerome Pouiller
2021-09-10 16:31   ` Kari Argillander
2021-09-10 16:54     ` Jérôme Pouiller
2021-09-10 17:01       ` Kari Argillander
2021-09-10 17:12         ` Jérôme Pouiller
2021-09-10 16:04 ` [PATCH 03/31] staging: wfx: ignore PS when STA/AP share same channel Jerome Pouiller
2021-09-10 16:04 ` [PATCH 04/31] staging: wfx: wait for SCAN_CMPL after a SCAN_STOP Jerome Pouiller
2021-09-10 16:04 ` Jerome Pouiller [this message]
2021-09-10 16:04 ` [PATCH 06/31] staging: wfx: drop unused argument from hif_scan() Jerome Pouiller
2021-09-10 16:04 ` [PATCH 07/31] staging: wfx: fix atomic accesses in wfx_tx_queue_empty() Jerome Pouiller
2021-09-10 16:04 ` [PATCH 08/31] staging: wfx: take advantage of wfx_tx_queue_empty() Jerome Pouiller
2021-09-10 16:04 ` [PATCH 09/31] staging: wfx: declare support for TDLS Jerome Pouiller
2021-09-10 16:04 ` [PATCH 10/31] staging: wfx: fix support for CSA Jerome Pouiller
2021-09-10 16:04 ` [PATCH 11/31] staging: wfx: relax the PDS existence constraint Jerome Pouiller
2021-09-10 16:04 ` [PATCH 12/31] staging: wfx: simplify API coherency check Jerome Pouiller
2021-09-10 16:04 ` [PATCH 13/31] staging: wfx: update with API 3.8 Jerome Pouiller
2021-09-10 16:43   ` Kari Argillander
2021-09-10 17:03     ` Jérôme Pouiller
2021-09-10 16:04 ` [PATCH 14/31] staging: wfx: uniformize counter names Jerome Pouiller
2021-09-10 16:04 ` [PATCH 15/31] staging: wfx: fix misleading 'rate_id' usage Jerome Pouiller
2021-09-10 16:04 ` [PATCH 16/31] staging: wfx: declare variables at beginning of functions Jerome Pouiller
2021-09-10 16:04 ` [PATCH 17/31] staging: wfx: simplify hif_join() Jerome Pouiller
2021-09-10 16:38   ` Kari Argillander
2021-09-10 16:04 ` [PATCH 18/31] staging: wfx: reorder function for slightly better eye candy Jerome Pouiller
2021-09-10 16:04 ` [PATCH 19/31] staging: wfx: fix error names Jerome Pouiller
2021-09-10 16:04 ` [PATCH 20/31] staging: wfx: apply naming rules in hif_tx_mib.c Jerome Pouiller
2021-09-10 16:04 ` [PATCH 21/31] staging: wfx: remove unused definition Jerome Pouiller
2021-09-10 16:04 ` [PATCH 22/31] staging: wfx: remove useless debug statement Jerome Pouiller
2021-09-10 16:04 ` [PATCH 23/31] staging: wfx: fix space after cast operator Jerome Pouiller
2021-09-10 16:04 ` [PATCH 24/31] staging: wfx: remove references to WFxxx in comments Jerome Pouiller
2021-09-10 16:04 ` [PATCH 25/31] staging: wfx: update files descriptions Jerome Pouiller
2021-09-10 16:04 ` [PATCH 26/31] staging: wfx: reformat comment Jerome Pouiller
2021-09-10 16:05 ` [PATCH 27/31] staging: wfx: avoid c99 comments Jerome Pouiller
2021-09-10 16:05 ` [PATCH 28/31] staging: wfx: fix comments styles Jerome Pouiller
2021-09-10 16:05 ` [PATCH 29/31] staging: wfx: remove useless comments after #endif Jerome Pouiller
2021-09-10 16:27   ` Kari Argillander
2021-09-10 16:49     ` Jérôme Pouiller
2021-09-10 17:05       ` Kari Argillander
2021-09-10 16:05 ` [PATCH 30/31] staging: wfx: explain the purpose of wfx_send_pds() Jerome Pouiller
2021-09-10 16:05 ` [PATCH 31/31] staging: wfx: indent functions arguments Jerome Pouiller
2021-09-10 16:57   ` Kari Argillander
2021-09-10 17:12     ` Jérôme Pouiller
2021-09-10 17:28       ` Kari Argillander
2021-09-10 17:07 ` [PATCH 00/31] [PATCH 00/31] staging/wfx: usual maintenance Kari Argillander
2021-09-10 17:15   ` Jérôme Pouiller

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=20210910160504.1794332-6-Jerome.Pouiller@silabs.com \
    --to=jerome.pouiller@silabs.com \
    --cc=davem@davemloft.net \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=kvalo@codeaurora.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).