[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251118072527.174375-1-andreas@kemnade.info>
Date: Tue, 18 Nov 2025 08:25:26 +0100
From: Andreas Kemnade <andreas@...nade.info>
To: briannorris@...omium.org,
francesco@...cini.it,
christophe.jaillet@...adoo.fr,
johannes.berg@...el.com,
rafael.beims@...adex.com,
andreas@...nade.info,
linux-wireless@...r.kernel.org,
linux-kernel@...r.kernel.org,
s.hauer@...gutronix.de
Subject: [RFC PATCH] wifi: mwifiex: try to fix some races with rmmod/modprobe
To debug some stability issues, some torture was done with the driver:
Doing rmmod mwifiex_sdio and modprobe mwifiex_sdio in a loop
this oops appeared:
[ 3261.934299] mwifiex_sdio mmc1:0001:1: PREP_CMD: FW is in bad state
[ 3261.988412] mwifiex_sdio mmc1:0001:1: info: shutdown mwifiex...
[ 3261.990081] mwifiex_sdio mmc1:0001:1: PREP_CMD: card is removed
[ 3262.052407] mwifiex_sdio mmc1:0001:1: ===mwifiex driverinfo dump start===
[ 3262.052864] mwifiex_sdio mmc1:0001:1: info: MWIFIEX VERSION: mwifiex 1.0 (16.92.21.p119)
[ 3262.053252] mwifiex_sdio mmc1:0001:1: SDIO register dump start
[ 3262.084733] mwifiex_sdio mmc1:0001:1: SDIO Func0 (0x0-0x9): 43 03 02 02 00 00 00 02 03 00
[ 3262.085574] mwifiex_sdio mmc1:0001:1: SDIO Func1 (0x10-0x17): 00 00 00 00 ff ff ff ff
[ 3262.093544] mwifiex_sdio mmc1:0001:1: SDIO Func1: (0x8) 00 (0x58) 00 (0x5c) 88 (0x5d) 00 (0x60) 07 (0x61) 0c (0x62) 00 (0x64) 10 (0x65) 00 (0x66) 00 (0x68) 00 (0x69) 00 (0x6a) 00
[ 3262.103543] mwifiex_sdio mmc1:0001:1: SDIO Func1 (0xe8-0xf2): dc fe 54 00 b0 00 1f 2a 24 14 70
[ 3262.325352] mwifiex_sdio mmc1:0001:1: SDIO Func1 (0xe8-0xf2): dc fe 6d 00 c7 00 1f 2a 24 14 70
[ 3262.325843] mwifiex_sdio mmc1:0001:1: SDIO register dump end
[ 3262.326626] mwifiex_sdio mmc1:0001:1: ===mwifiex driverinfo dump end===
[ 3262.327096] mwifiex_sdio mmc1:0001:1: == mwifiex firmware dump start ==
[ 3291.379005] mwifiex_sdio mmc1:0001:1: == mwifiex firmware dump end ==
[ 3291.381143] mwifiex_sdio mmc1:0001:1: == mwifiex dump information to /sys/class/devcoredump start
[ 3291.382047] mwifiex_sdio mmc1:0001:1: == mwifiex dump information to /sys/class/devcoredump end
[ 3291.382148] 8<--- cut here ---
[ 3291.382210] Unable to handle kernel NULL pointer dereference at virtual address 00000064 when read
[ 3291.382265] [00000064] *pgd=00000000
[ 3291.382334] Internal error: Oops: 5 [#1] SMP ARM
[ 3291.426597] Modules linked in: mwifiex_sdio(-) netconsole mwifiex jd9930_regulator imx_sdma btnxpuart crc8 [last unloaded: mwifiex_sdio]
[ 3291.438980] CPU: 0 UID: 0 PID: 751 Comm: kworker/0:1 Not tainted 6.18.0-rc3-00003-g5a1efae8dc10-dirty #338 VOLUNTARY
[ 3291.449655] Hardware name: Freescale i.MX6 SoloLite (Device Tree)
[ 3291.455829] Workqueue: events mwifiex_sdio_work [mwifiex_sdio]
[ 3291.461749] PC is at mwifiex_sdio_work+0x6d0/0x8ac [mwifiex_sdio]
card->adapter is NULL and therefore in mwifiex_sdio_card_reset_work
NULL pointer issues appear. The long execution time of the dumping
functions increases the probability that card->adapter changes
in mwifiex_sdio_card_work().
mwifiex_unregister_dev is the place to set card->adapter to NULL.
So add some NULL pointer checks to work around it a bit.
But this really smells like missing locking. So the proper solution
would be to add a mutex and locking. But it is a bit unclear
how to do that really.
This dirty fix seem to improve things when device is not touched.
But if it is used, there are other races:
- calling wiphy_unregister with invalid pointer
- rkill unregister issues
- module count going to -1
Signed-off-by: Andreas Kemnade <andreas@...nade.info>
---
drivers/net/wireless/marvell/mwifiex/sdio.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index f039d6f19183..2808cff6fd56 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -947,6 +947,10 @@ static void mwifiex_sdio_coredump(struct device *dev)
struct sdio_mmc_card *card;
card = sdio_get_drvdata(func);
+ if (!card->adapter) {
+ dev_err(dev, "adapter is not valid, cannot coredump\n");
+ return;
+ }
if (!test_and_set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
&card->work_flags))
schedule_work(&card->work);
@@ -3019,9 +3023,19 @@ static void mwifiex_sdio_work(struct work_struct *work)
struct sdio_mmc_card *card =
container_of(work, struct sdio_mmc_card, work);
+ if (!card->adapter) {
+ pr_err("sdio_work: no adapter\n");
+ return;
+ }
+
if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
&card->work_flags))
mwifiex_sdio_device_dump_work(card->adapter);
+
+ if (!card->adapter) {
+ pr_err("sdio_work: no adapter to reset\n");
+ return;
+ }
if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
&card->work_flags))
mwifiex_sdio_card_reset_work(card->adapter);
--
2.47.3
Powered by blists - more mailing lists