* [PATCH] wifi: iwlegacy: serialize watchdog updates with device teardown
@ 2026-10-04 11:45 Runyu Xiao
2026-10-05 13:23 ` Johannes Berg
0 siblings, 1 reply; 2+ messages in thread
From: Runyu Xiao @ 2026-10-04 11:45 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: Julia Lawall, Kalle Valo, linux-wireless, linux-kernel, stable,
Runyu Xiao, Jianhao Xu
The writable wd_timeout debugfs file changes il->cfg->wd_timeout, but the
iwl3945 configuration is shared and const. The handler also rearms the
watchdog without taking il->mutex. The down paths hold this mutex, delete
the timer, and then free the TX queues, so an unlocked debugfs write can
rearm the timer after deletion. The callback can then access the queues
after they have been freed.
Store wd_timeout in per-device state. Serialize the debugfs update with
the down paths and only arm the watchdog while TX queues exist. Use
READ_ONCE() and WRITE_ONCE() for accesses that do not hold il->mutex.
Fixes: 1dc80798a8ca ("iwlegacy: constify local structures")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
drivers/net/wireless/intel/iwlegacy/3945-mac.c | 1 +
drivers/net/wireless/intel/iwlegacy/4965-mac.c | 1 +
drivers/net/wireless/intel/iwlegacy/common.c | 6 +++---
drivers/net/wireless/intel/iwlegacy/common.h | 1 +
drivers/net/wireless/intel/iwlegacy/debug.c | 8 ++++++--
5 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
index cbaf250626..ee40cf534d 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
@@ -3563,6 +3563,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
D_INFO("*** LOAD DRIVER ***\n");
il->cfg = cfg;
+ il->wd_timeout = cfg->wd_timeout;
il->ops = &il3945_ops;
#ifdef CONFIG_IWLEGACY_DEBUGFS
il->debugfs_ops = &il3945_debugfs_ops;
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
index 18bb556826..9a42a74cf8 100644
--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
@@ -6500,6 +6500,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
D_INFO("*** LOAD DRIVER ***\n");
il->cfg = cfg;
+ il->wd_timeout = cfg->wd_timeout;
il->ops = &il4965_ops;
#ifdef CONFIG_IWLEGACY_DEBUGFS
il->debugfs_ops = &il4965_debugfs_ops;
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
index 0bb807ff8e..c2adb1ef63 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -4774,7 +4774,7 @@ il_check_stuck_queue(struct il_priv *il, int cnt)
timeout =
txq->time_stamp +
- msecs_to_jiffies(il->cfg->wd_timeout);
+ msecs_to_jiffies(READ_ONCE(il->wd_timeout));
if (time_after(now, timeout)) {
IL_ERR("Queue %d stuck for %u ms.\n", q->id,
@@ -4806,7 +4806,7 @@ il_bg_watchdog(struct timer_list *t)
if (test_bit(S_EXIT_PENDING, &il->status))
return;
- timeout = il->cfg->wd_timeout;
+ timeout = READ_ONCE(il->wd_timeout);
if (timeout == 0)
return;
@@ -4831,7 +4831,7 @@ EXPORT_SYMBOL(il_bg_watchdog);
void
il_setup_watchdog(struct il_priv *il)
{
- unsigned int timeout = il->cfg->wd_timeout;
+ unsigned int timeout = READ_ONCE(il->wd_timeout);
if (timeout)
mod_timer(&il->watchdog,
diff --git a/drivers/net/wireless/intel/iwlegacy/common.h b/drivers/net/wireless/intel/iwlegacy/common.h
index 21f1c7702a..9c1c252dcc 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.h
+++ b/drivers/net/wireless/intel/iwlegacy/common.h
@@ -1129,6 +1129,7 @@ struct il_priv {
struct ieee80211_rate *ieee_rates;
struct il_cfg *cfg;
+ unsigned int wd_timeout;
const struct il_ops *ops;
#ifdef CONFIG_IWLEGACY_DEBUGFS
const struct il_debugfs_ops *debugfs_ops;
diff --git a/drivers/net/wireless/intel/iwlegacy/debug.c b/drivers/net/wireless/intel/iwlegacy/debug.c
index 8a9f79ff1c..13dfc263a2 100644
--- a/drivers/net/wireless/intel/iwlegacy/debug.c
+++ b/drivers/net/wireless/intel/iwlegacy/debug.c
@@ -1284,8 +1284,12 @@ il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,
if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
timeout = IL_DEF_WD_TIMEOUT;
- il->cfg->wd_timeout = timeout;
- il_setup_watchdog(il);
+ mutex_lock(&il->mutex);
+ WRITE_ONCE(il->wd_timeout, timeout);
+ if (il->txq)
+ il_setup_watchdog(il);
+ mutex_unlock(&il->mutex);
+
return count;
}
--
2.34.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] wifi: iwlegacy: serialize watchdog updates with device teardown
2026-10-04 11:45 [PATCH] wifi: iwlegacy: serialize watchdog updates with device teardown Runyu Xiao
@ 2026-10-05 13:23 ` Johannes Berg
0 siblings, 0 replies; 2+ messages in thread
From: Johannes Berg @ 2026-10-05 13:23 UTC (permalink / raw)
To: Runyu Xiao, Stanislaw Gruszka
Cc: Julia Lawall, Kalle Valo, linux-wireless, linux-kernel, stable,
Jianhao Xu
On Sun, 2026-10-04 at 19:45 +0800, Runyu Xiao wrote:
> The writable wd_timeout debugfs file changes il->cfg->wd_timeout, but the
> iwl3945 configuration is shared and const. The handler also rearms the
> watchdog without taking il->mutex. The down paths hold this mutex, delete
> the timer, and then free the TX queues, so an unlocked debugfs write can
> rearm the timer after deletion. The callback can then access the queues
> after they have been freed.
>
> Store wd_timeout in per-device state. Serialize the debugfs update with
> the down paths and only arm the watchdog while TX queues exist. Use
> READ_ONCE() and WRITE_ONCE() for accesses that do not hold il->mutex.
>
That's a stupid commit log, I can see what you changed.
johannes
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-05 13:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-04 11:45 [PATCH] wifi: iwlegacy: serialize watchdog updates with device teardown Runyu Xiao
2026-10-05 13:23 ` Johannes Berg
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®