mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Zhao Li <enderaoelyther@gmail.com>
To: Johannes Berg <johannes@sipsolutions.net>
Cc: "Sebastian Krzyszkowiak" <sebastian.krzyszkowiak@puri.sm>,
	"Arend van Spriel" <arend.vanspriel@broadcom.com>,
	"Ville Nummela" <ville.nummela@kempower.com>,
	"Jiangshan Yi" <yijiangshan@kylinos.cn>,
	"Marek Vasut" <marex@nabladev.com>,
	"Toke Høiland-Jørgensen" <toke@toke.dk>,
	"Stefan Hansson" <newbyte@postmarketos.org>,
	"Ping-Ke Shih" <pkshih@realtek.com>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Ethan Nelson-Moore" <enelsonmoore@gmail.com>,
	"Pengpeng Hou" <pengpeng@iscas.ac.cn>,
	"Prameela Rani Garnepudi" <prameela.j04cs@gmail.com>,
	"Siva Rebbagondla" <siva.rebbagondla@redpinesignals.com>,
	"Kalle Valo" <kvalo@kernel.org>,
	linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: [PATCH 3/3] wifi: rsi: serialize background scan state
Date: Wed, 28 Oct 2026 22:19:27 +0800	[thread overview]
Message-ID: <20261028141927.9306-4-enderaoelyther@gmail.com> (raw)
In-Reply-To: <20261028141927.9306-1-enderaoelyther@gmail.com>

The firmware completion event runs in the RX thread without
common->mutex, while scan cancellation can clear hwscan under that mutex.
Both paths test bgscan_en before sending STOP and reporting completion.
An interleaving can therefore dereference a NULL or freed request in
rsi_send_bgscan_params(), or report the scan twice.

The RX path cannot take common->mutex: rsi_mac80211_start() holds it while
waiting for that path to finish firmware initialization after
hibernation.

Add a scan-specific mutex and use it to serialize start, cancellation,
and firmware completion. Clear bgscan_en and hwscan together even when
STOP cannot be queued so a later event cannot report the same scan again.

LLM assistance was used to find the bug and review.

Fixes: 7fdcb8e12660 ("rsi: add support for hardware scan offload")
Cc: stable@vger.kernel.org
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
---
Validation: W=1 module builds with MODPOST passed with CONFIG_RSI_COEX
enabled and disabled. Not reproduced; RS9113/RS9116 hardware was
unavailable.
Sparse C=2 passed. Targeted Smatch introduced no new diagnostics.
Host state is serialized, but no hardware or protocol evidence established
how a late event from a scan whose STOP command was not queued is attributed
after a later scan starts.

 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 31 +++++++++++++++------
 drivers/net/wireless/rsi/rsi_91x_main.c     |  1 +
 drivers/net/wireless/rsi/rsi_91x_mgmt.c     | 16 +++++++----
 drivers/net/wireless/rsi/rsi_main.h         |  2 ++
 4 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index a2e981e261d6..5617c7ef6196 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -249,15 +249,21 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
 	    scan_req->n_channels == 0)
 		return -EINVAL;
 
+	mutex_lock(&common->scan_mutex);
+
 	/* Scan already in progress. So return */
-	if (common->bgscan_en)
-		return -EBUSY;
+	if (common->bgscan_en) {
+		ret = -EBUSY;
+		goto out;
+	}
 
 	/* If STA is not connected, return with special value 1, in order
 	 * to start sw_scan in mac80211
 	 */
-	if (!vif->cfg.assoc)
-		return 1;
+	if (!vif->cfg.assoc) {
+		ret = 1;
+		goto out;
+	}
 
 	mutex_lock(&common->mutex);
 	common->hwscan = scan_req;
@@ -270,6 +276,9 @@ static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
 	}
 	mutex_unlock(&common->mutex);
 
+out:
+	mutex_unlock(&common->scan_mutex);
+
 	return ret;
 }
 
@@ -283,16 +292,20 @@ static void rsi_mac80211_cancel_hw_scan(struct ieee80211_hw *hw,
 	};
 
 	rsi_dbg(INFO_ZONE, "***** Hardware scan stop *****\n");
-	mutex_lock(&common->mutex);
+	mutex_lock(&common->scan_mutex);
 
 	if (common->bgscan_en) {
-		if (!rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
-			common->bgscan_en = false;
+		mutex_lock(&common->mutex);
+		if (rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
+			rsi_dbg(ERR_ZONE, "Failed to stop background scan\n");
+		mutex_unlock(&common->mutex);
+		common->bgscan_en = false;
+		common->hwscan = NULL;
 		ieee80211_scan_completed(adapter->hw, &info);
 		rsi_dbg(INFO_ZONE, "Back ground scan cancelled\n");
 	}
-	common->hwscan = NULL;
-	mutex_unlock(&common->mutex);
+
+	mutex_unlock(&common->scan_mutex);
 }
 
 /**
diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c
index 2ce514766620..16f57c964ca3 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -325,6 +325,7 @@ struct rsi_hw *rsi_91x_init(u16 oper_mode)
 
 	rsi_init_event(&common->tx_thread.event);
 	mutex_init(&common->mutex);
+	mutex_init(&common->scan_mutex);
 	mutex_init(&common->tx_lock);
 	mutex_init(&common->rx_lock);
 	mutex_init(&common->tx_bus_mutex);
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 165423313c5f..5f11de44f880 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -2107,17 +2107,23 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
 		rsi_dbg(INFO_ZONE, "Wakeup/Sleep confirmation.\n");
 		return rsi_handle_ps_confirm(adapter, msg);
 
-	case BG_SCAN_PROBE_REQ:
+	case BG_SCAN_PROBE_REQ: {
+		struct cfg80211_scan_info info = {};
+
 		rsi_dbg(INFO_ZONE, "BG scan complete event\n");
+		mutex_lock(&common->scan_mutex);
 		if (common->bgscan_en) {
-			struct cfg80211_scan_info info = {};
-
-			if (!rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
-				common->bgscan_en = 0;
+			if (rsi_send_bgscan_params(common, RSI_STOP_BGSCAN))
+				rsi_dbg(ERR_ZONE,
+					"Failed to stop background scan\n");
+			common->bgscan_en = false;
+			common->hwscan = NULL;
 			ieee80211_scan_completed(adapter->hw, &info);
 		}
+		mutex_unlock(&common->scan_mutex);
 		rsi_dbg(INFO_ZONE, "Background scan completed\n");
 		break;
+	}
 
 	default:
 		rsi_dbg(INFO_ZONE, "%s: Invalid TA confirm pkt received\n",
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index dcf8fb40698b..5fa8fd93a17e 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -250,6 +250,8 @@ struct rsi_common {
 	struct completion wlan_init_completion;
 	/* Mutex declaration */
 	struct mutex mutex;
+	/* Protect background scan state. */
+	struct mutex scan_mutex;
 	/* Mutex used for tx thread */
 	struct mutex tx_lock;
 	/* Mutex used for rx thread */
-- 
2.56.0


      parent reply	other threads:[~2026-10-28 14:20 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-28 14:19 [PATCH 0/3] wifi: rsi: fix background scan result and state lifetime Zhao Li
2026-10-28 14:19 ` [PATCH 1/3] wifi: rsi: initialize background scan completion data Zhao Li
2026-10-28 14:19 ` [PATCH 2/3] wifi: rsi: report background scan start failures Zhao Li
2026-10-28 14:19 ` Zhao Li [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=20261028141927.9306-4-enderaoelyther@gmail.com \
    --to=enderaoelyther@gmail.com \
    --cc=arend.vanspriel@broadcom.com \
    --cc=enelsonmoore@gmail.com \
    --cc=johannes@sipsolutions.net \
    --cc=kuba@kernel.org \
    --cc=kvalo@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=marex@nabladev.com \
    --cc=newbyte@postmarketos.org \
    --cc=pengpeng@iscas.ac.cn \
    --cc=pkshih@realtek.com \
    --cc=prameela.j04cs@gmail.com \
    --cc=sebastian.krzyszkowiak@puri.sm \
    --cc=siva.rebbagondla@redpinesignals.com \
    --cc=stable@vger.kernel.org \
    --cc=toke@toke.dk \
    --cc=ville.nummela@kempower.com \
    --cc=yijiangshan@kylinos.cn \
    /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

all inboxes | Powered by JetHome®