From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Ville Nummela <ville.nummela@kempower.com>,
Johannes Berg <johannes.berg@intel.com>,
Sasha Levin <sashal@kernel.org>,
linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 7.0-5.10] wifi: rsi_91x_usb: do not pause rfkill polling when stopping mac80211
Date: Mon, 20 Apr 2026 09:16:48 -0400 [thread overview]
Message-ID: <20260420132314.1023554-14-sashal@kernel.org> (raw)
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>
From: Ville Nummela <ville.nummela@kempower.com>
[ Upstream commit 777d8ba5aada960c666f810d5d820ab55ebb64c3 ]
Removing rsi_91x USB adapter could cause rtnetlink to lock up.
When rsi_mac80211_stop is called, wiphy_lock is locked. Call to
wiphy_rfkill_stop_polling would wait until the work queue has
finished, but because the work queue waits for wiphy_lock, that
would never happen.
Moving the call to rsi_disconnect avoids the lock up.
Signed-off-by: Ville Nummela <ville.nummela@kempower.com>
Link: https://patch.msgid.link/20260318081912.87744-1-ville.nummela@kempower.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have all the information needed. Let me compile the full analysis.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject Line
- **Subsystem**: `wifi: rsi_91x_usb` (USB WiFi driver for RSI 91x
chipset)
- **Action verb**: "do not pause" - indicates preventing incorrect
behavior that causes a hang
- **Summary**: Stop rfkill polling from being paused during mac80211
stop, which causes a deadlock
Record: [wifi: rsi_91x_usb] [do not pause] [Avoid deadlock by moving
rfkill stop polling out of mac80211 stop callback]
### Step 1.2: Tags
- **Signed-off-by**: Ville Nummela (author, external contributor from
Kempower)
- **Link**: `https://patch.msgid.link/20260318081912.87744-1-
ville.nummela@kempower.com`
- **Signed-off-by**: Johannes Berg (Intel, the wireless subsystem
maintainer - applied the patch)
- No Fixes: tag (expected for manual review)
- No Reported-by, Tested-by, Reviewed-by
Record: Patch authored by external contributor (Ville Nummela), applied
by the wifi subsystem maintainer (Johannes Berg). No explicit stable
nomination.
### Step 1.3: Commit Body Analysis
The message describes a **deadlock**:
1. Removing the RSI USB adapter causes rtnetlink to lock up
2. `rsi_mac80211_stop` is called with `wiphy_lock` held
3. `wiphy_rfkill_stop_polling` calls `cancel_delayed_work_sync`, which
waits for the rfkill poll work to finish
4. The rfkill poll work needs `wiphy_lock` to complete (via
`guard(wiphy)` in `cfg80211_rfkill_poll`)
5. Classic ABBA deadlock: Thread A holds wiphy_lock, waits for work;
work needs wiphy_lock
Record: Real deadlock. Trigger: USB adapter removal. Failure: system
hang (rtnetlink lockup).
### Step 1.4: Hidden Bug Fix Detection
This is explicitly a deadlock fix, not disguised. The description
clearly explains the locking inversion.
Record: Explicit deadlock fix, not hidden.
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
- **Files changed**: 3
- `drivers/net/wireless/rsi/rsi_91x_mac80211.c`: +16/-1 (new function
+ remove call)
- `drivers/net/wireless/rsi/rsi_91x_usb.c`: +2/-0 (call new function)
- `drivers/net/wireless/rsi/rsi_common.h`: +1/-0 (declare new
function)
- **Total**: ~19 lines added, 1 removed
- **Functions modified**: `rsi_mac80211_stop()` (removed
`wiphy_rfkill_stop_polling` call), `rsi_disconnect()` (added call to
new function)
- **Functions added**: `rsi_mac80211_rfkill_exit()` (new helper)
- **Scope**: Small, single-subsystem, well-contained
### Step 2.2: Code Flow Change
1. **rsi_mac80211_stop()**: BEFORE: called `wiphy_rfkill_stop_polling()`
while holding `common->mutex` (and with `wiphy_lock` held by caller).
AFTER: no longer calls it.
2. **rsi_disconnect()** (USB): BEFORE: went straight to
`rsi_mac80211_detach()`. AFTER: calls `rsi_mac80211_rfkill_exit()`
first (without wiphy_lock held), then `rsi_mac80211_detach()`.
3. **New `rsi_mac80211_rfkill_exit()`**: Calls
`wiphy_rfkill_stop_polling()` without wiphy_lock held, breaking the
deadlock.
### Step 2.3: Bug Mechanism
- **Category**: Deadlock/lock ordering
- **Mechanism**: `rsi_mac80211_stop()` (called with `wiphy_lock` held)
invokes `wiphy_rfkill_stop_polling()` which calls
`cancel_delayed_work_sync()`. The work item (`cfg80211_rfkill_poll`)
needs `wiphy_lock`. Classic ABBA deadlock.
- **Fix**: Move the polling stop to `rsi_disconnect()`, before
`rsi_mac80211_detach()`, where `wiphy_lock` is NOT held.
### Step 2.4: Fix Quality
- Obviously correct: removes the deadlocking call from the locked
context, moves it to unlocked context
- Minimal/surgical: small change, well-contained within the rsi driver
- Other drivers (ath9k, rtlwifi, mt76, etc.) all call
`wiphy_rfkill_stop_polling()` from their deinit paths, NOT from
`.stop` - confirming this is the right pattern
- Regression risk: very low. The rfkill polling is stopped slightly
earlier in the teardown sequence
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
- `wiphy_rfkill_stop_polling(hw->wiphy)` in `rsi_mac80211_stop()` was
added by commit `edba3532c65223` ("rsi: add support for rf-kill
functionality") by Pavani Muthyala, 2017-08-03.
- The deadlock was introduced when `cfg80211_rfkill_poll()` acquired
wiphy_lock: commit `8e2f6f2366219` ("wifi: cfg80211: lock wiphy mutex
for rfkill poll") by Johannes Berg, 2023-11-24, first in v6.7-rc4.
- `drv_stop()` has had `lockdep_assert_wiphy()` since commit
`0e8185ce1ddebf` (v6.7-rc1).
Record: Bug is a latent deadlock since v6.7 (when wiphy_lock was added
to the rfkill poll path). Buggy rfkill call in rsi since 2017, but it
only became a deadlock with v6.7.
### Step 3.2: No Fixes: tag present (expected).
### Step 3.3: File History
Recent changes to rsi files are mostly cleanups and unrelated bug fixes.
No prerequisites identified.
### Step 3.4: Author
Ville Nummela appears to be an external contributor (Kempower). This is
their first rsi commit. However, the patch was applied by Johannes Berg,
the wifi subsystem maintainer.
### Step 3.5: Dependencies
The fix is standalone. It uses only existing APIs
(`wiphy_rfkill_stop_polling`) and creates a simple wrapper function. No
dependencies on other patches.
## PHASE 4: MAILING LIST RESEARCH
Lore is protected by anti-bot measures, preventing direct access. B4 dig
could not find the commit in the local tree. The Link tag confirms the
patch was submitted and reviewed through the standard wireless-next
workflow and applied by Johannes Berg.
Record: Could not access lore discussion. Patch applied by subsystem
maintainer.
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Functions Modified
- `rsi_mac80211_stop()` - the `.stop` mac80211 callback
- `rsi_disconnect()` - USB disconnect handler
- New: `rsi_mac80211_rfkill_exit()`
### Step 5.2: Callers
- `rsi_mac80211_stop()` is called by mac80211 via `drv_stop()`
(confirmed: `lockdep_assert_wiphy()` at driver-ops.c:39). Called when
interface goes down.
- `rsi_disconnect()` is the USB `.disconnect` callback, called by USB
subsystem on device removal.
### Step 5.3-5.4: Call Chain for Deadlock
Verified complete deadlock chain:
1. USB removal -> `rsi_disconnect()` -> `rsi_mac80211_detach()` ->
`ieee80211_unregister_hw()` -> interface shutdown -> `drv_stop()`
[acquires wiphy_lock] -> `rsi_mac80211_stop()`
2. `rsi_mac80211_stop()` -> `wiphy_rfkill_stop_polling()` ->
`rfkill_pause_polling()` ->
`cancel_delayed_work_sync(&rfkill->poll_work)`
3. Work item: `rfkill_poll()` -> `cfg80211_rfkill_poll()` ->
`guard(wiphy)(&rdev->wiphy)` [tries to acquire wiphy_lock] -> BLOCKED
### Step 5.5: Similar Patterns
All other wifi drivers (ath9k, rtlwifi, mt76, rtl818x, brcmsmac) call
`wiphy_rfkill_stop_polling()` from their deinit/disconnect path, NOT
from `.stop`. RSI was unique in calling it from `.stop`.
## PHASE 6: STABLE TREE ANALYSIS
### Step 6.1: Buggy Code in Stable
- The deadlock requires both:
- `wiphy_rfkill_stop_polling()` in `rsi_mac80211_stop()` (since 2017,
commit edba3532)
- `wiphy_lock` acquisition in `cfg80211_rfkill_poll()` (since v6.7,
commit 8e2f6f23)
- The deadlock exists in v6.7+ stable trees (6.12.y, 6.6.y if 8e2f6f23
was backported)
### Step 6.2: Backport Complications
The fix is simple and self-contained. The rsi driver code in this area
has been stable. Clean apply expected for recent stable trees.
### Step 6.3: No related fixes already in stable.
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
- **Subsystem**: wifi (drivers/net/wireless/rsi/) - USB WiFi driver
- **Criticality**: IMPORTANT - WiFi is commonly used, RSI chipsets are
used in embedded/IoT
- **Maintainer**: Applied by Johannes Berg (the wireless subsystem
maintainer), strong trust signal
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Affected Users
Users of RSI 91x USB WiFi adapters. When removing the adapter
(physically or via software), the system hangs.
### Step 8.2: Trigger Conditions
- **Trigger**: Removing RSI USB WiFi adapter (unplug or modprobe -r)
- **Frequency**: Every time the adapter is removed
- **Unprivileged**: Physical access needed, but could also be triggered
by system suspend/resume or hotplug events
### Step 8.3: Failure Mode Severity
- **Failure mode**: System hang / deadlock (rtnetlink locks up)
- **Severity**: CRITICAL - system becomes partially or fully unusable;
rtnetlink lockup affects all networking operations
### Step 8.4: Risk-Benefit
- **Benefit**: HIGH - prevents guaranteed system hang on USB adapter
removal
- **Risk**: VERY LOW - 19 lines changed, moves existing call to correct
context, pattern matches all other wifi drivers
- **Ratio**: Strongly favorable
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence Summary
**FOR backporting:**
- Fixes a real, reproducible deadlock (system hang) on USB adapter
removal
- Small, surgical fix (~20 lines across 3 files in one driver)
- Obviously correct: moves `wiphy_rfkill_stop_polling()` from locked
context to unlocked context
- Pattern matches all other wifi drivers (ath9k, rtlwifi, mt76, etc.)
- Applied by wireless subsystem maintainer (Johannes Berg)
- Standalone fix with no dependencies
- Bug exists since v6.7 (when wiphy_lock was added to rfkill poll)
**AGAINST backporting:**
- No explicit stable nomination or Fixes: tag (expected for manual
review)
- Only fixes USB path (SDIO has same latent issue but wasn't addressed -
minor concern)
- Author is external contributor with no previous rsi commits (mitigated
by maintainer sign-off)
### Step 9.2: Stable Rules Checklist
1. Obviously correct and tested? **YES** - clear deadlock fix, correct
locking pattern
2. Fixes a real bug? **YES** - deadlock causing system hang
3. Important issue? **YES** - deadlock = CRITICAL severity
4. Small and contained? **YES** - ~20 lines in one driver
5. No new features or APIs? **YES** - only moves existing functionality
6. Can apply to stable trees? **YES** - standalone, no dependencies
### Step 9.3: Exception Categories
Not an exception case - this is a straightforward deadlock fix.
### Step 9.4: Decision
This is a clear, small, surgical fix for a real deadlock that causes
system hang when removing an RSI USB WiFi adapter. It follows the same
pattern used by all other wifi drivers. Applied by the wifi subsystem
maintainer.
## Verification
- [Phase 1] Parsed tags: Link to patch.msgid.link, SOB by author and
Johannes Berg (maintainer)
- [Phase 2] Diff analysis: 1 line removed from `rsi_mac80211_stop()`,
16-line new function `rsi_mac80211_rfkill_exit()` added, 2 lines
calling it in `rsi_disconnect()`
- [Phase 3] git blame: `wiphy_rfkill_stop_polling` in `.stop` added by
edba3532c65223 (2017)
- [Phase 3] git show 8e2f6f2366219: confirmed `wiphy_lock` added to
`cfg80211_rfkill_poll()` in v6.7-rc4
- [Phase 3] git show 0e8185ce1ddebf: confirmed `lockdep_assert_wiphy()`
in `drv_stop()` since v6.7-rc1
- [Phase 3] git describe --contains 8e2f6f2366219: deadlock exists since
v6.7-rc4
- [Phase 4] Could not access lore (anti-bot protection); patch Link tag
confirms standard review
- [Phase 5] Verified deadlock chain: `drv_stop()` holds wiphy_lock
(driver-ops.c:39) -> `rsi_mac80211_stop()` -> `rfkill_pause_polling()`
-> `cancel_delayed_work_sync()` blocks on work item needing wiphy_lock
via `guard(wiphy)` in `cfg80211_rfkill_poll()` (core.c:224)
- [Phase 5] Confirmed all other wifi drivers (ath9k, rtlwifi, mt76,
rtl818x, brcmsmac) call `wiphy_rfkill_stop_polling()` from deinit
path, not `.stop`
- [Phase 6] Bug exists in v6.7+ trees; code in rsi driver unchanged in
affected area
- [Phase 8] Failure mode: deadlock/system hang, severity CRITICAL
- UNVERIFIED: Could not access lore discussion for reviewer feedback
**YES**
drivers/net/wireless/rsi/rsi_91x_mac80211.c | 17 ++++++++++++++++-
drivers/net/wireless/rsi/rsi_91x_usb.c | 2 ++
drivers/net/wireless/rsi/rsi_common.h | 1 +
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index c7ae8031436ae..3faf2235728be 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -325,6 +325,22 @@ void rsi_mac80211_detach(struct rsi_hw *adapter)
}
EXPORT_SYMBOL_GPL(rsi_mac80211_detach);
+/**
+ * rsi_mac80211_rfkill_exit() - This function is used to stop rfkill polling
+ * when the device is removed.
+ * @adapter: Pointer to the adapter structure.
+ *
+ * Return: None.
+ */
+void rsi_mac80211_rfkill_exit(struct rsi_hw *adapter)
+{
+ struct ieee80211_hw *hw = adapter->hw;
+
+ if (hw)
+ wiphy_rfkill_stop_polling(hw->wiphy);
+}
+EXPORT_SYMBOL_GPL(rsi_mac80211_rfkill_exit);
+
/**
* rsi_indicate_tx_status() - This function indicates the transmit status.
* @adapter: Pointer to the adapter structure.
@@ -422,7 +438,6 @@ static void rsi_mac80211_stop(struct ieee80211_hw *hw, bool suspend)
rsi_dbg(ERR_ZONE, "===> Interface DOWN <===\n");
mutex_lock(&common->mutex);
common->iface_down = true;
- wiphy_rfkill_stop_polling(hw->wiphy);
/* Block all rx frames */
rsi_send_rx_filter_frame(common, 0xffff);
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index d83204701e27e..8765cac6f875b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -877,6 +877,8 @@ static void rsi_disconnect(struct usb_interface *pfunction)
if (!adapter)
return;
+ rsi_mac80211_rfkill_exit(adapter);
+
rsi_mac80211_detach(adapter);
if (IS_ENABLED(CONFIG_RSI_COEX) && adapter->priv->coex_mode > 1 &&
diff --git a/drivers/net/wireless/rsi/rsi_common.h b/drivers/net/wireless/rsi/rsi_common.h
index 7aa5124575cfe..591602beeec68 100644
--- a/drivers/net/wireless/rsi/rsi_common.h
+++ b/drivers/net/wireless/rsi/rsi_common.h
@@ -79,6 +79,7 @@ static inline int rsi_kill_thread(struct rsi_thread *handle)
}
void rsi_mac80211_detach(struct rsi_hw *hw);
+void rsi_mac80211_rfkill_exit(struct rsi_hw *hw);
u16 rsi_get_connected_channel(struct ieee80211_vif *vif);
struct rsi_hw *rsi_91x_init(u16 oper_mode);
void rsi_91x_deinit(struct rsi_hw *adapter);
--
2.53.0
next prev parent reply other threads:[~2026-04-20 13:23 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260420132314.1023554-1-sashal@kernel.org>
2026-04-20 13:16 ` [PATCH AUTOSEL 7.0-6.18] wifi: ath12k: Fix the assignment of logical link index Sasha Levin
2026-04-20 13:16 ` [PATCH AUTOSEL 7.0-6.12] wifi: rtw89: ser: Wi-Fi 7 reset HALT C2H after reading it Sasha Levin
2026-04-20 13:16 ` Sasha Levin [this message]
2026-04-20 13:16 ` [PATCH AUTOSEL 7.0-6.18] wifi: rtw88: add quirks to disable PCI ASPM and deep LPS for HP P3S95EA#ACB Sasha Levin
2026-04-20 13:16 ` [PATCH AUTOSEL 6.18] wifi: brcmfmac: validate bsscfg indices in IF events Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-6.6] wifi: mac80211: set band information only for non-MLD when probing stations using NULL frame Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-6.19] wifi: mt76: avoid to set ACK for MCU command if wait_resp is not set Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-6.19] wifi: rtw89: Add support for TP-Link Archer TX50U Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-6.1] wifi: mac80211: use ap_addr for 4-address NULL frame destination Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-6.18] wifi: ath12k: Set up MLO after SSR Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-6.18] wifi: iwlwifi: mld: always assign a fw id to a vif Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] wifi: wl1251: validate packet IDs before indexing tx_frames Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-6.18] wifi: mt76: flush pending TX before channel switch Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-6.6] wifi: mt76: fix list corruption in mt76_wcid_cleanup Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-6.12] wifi: mt76: add missing lock protection in mt76_sta_state for sta_event callback Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.18] wifi: mt76: mt7996: Disable Rx hdr_trans in monitor mode Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.18] wifi: iwlwifi: restrict TOP reset to some devices Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.12] wifi: mt76: mt7925: Skip scan process during suspend Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-5.10] wifi: mt76: mt76x02: wake queues after reconfig Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.12] wifi: mt76: mt7925: resolve link after acquiring mt76 mutex Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.19] wifi: rtw89: mac: remove A-die off setting for RTL8852C and RTL8922A Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.18] wifi: mt76: mt7996: fix queue pause after scan due to wrong channel switch reason Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.18] wifi: brcmfmac: of: defer probe for MAC address Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.19] wifi: rtw89: Add support for Buffalo WI-U3-2400XE2 Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.19] wifi: rtw89: Add support for Elecom WDC-XE2402TU3-B Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.6] wifi: mt76: mt7996: reset device after MCU message timeout Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-5.10] wifi: rtw88: TX QOS Null data the same way as Null data Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-6.18] wifi: rtw88: validate RX rate to prevent out-of-bound Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-6.18] wifi: ath12k: Skip adding inactive partner vdev info Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-6.18] wifi: mt76: mt7996: fix frequency separation for station STR mode Sasha Levin
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=20260420132314.1023554-14-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=johannes.berg@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
--cc=ville.nummela@kempower.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