From 3aa1dcaa4f6f5ae08936491e08bd456f331f2d40 Mon Sep 17 00:00:00 2001 From: Mikhail Gavrilov Date: Tue, 4 Aug 2026 17:00:04 +0500 Subject: [PATCH] Revert "wifi: mt76: Disable napi when removing device" This reverts commit 13b7e6a96a005c656d38f3da51581deaf9866375. That commit made mt76_dma_cleanup() disable every RX NAPI instance before deleting it, to silence WARNs in __netif_napi_del_locked() and page_pool_disable_direct_recycling() seen when unloading mt7915e with an MT7916. On mt7921e and mt7925e the same instances are already disabled earlier, in mt7921e_unregister_device() and mt7925e_unregister_device(), which only afterwards call mt792x_dma_cleanup() -> mt76_dma_cleanup(). Each instance is therefore disabled twice, and napi_disable() is not idempotent: on return it leaves NAPIF_STATE_SCHED and NAPIF_STATE_NPSVC set, so the second call spins in usleep_range() forever, waiting for bits that nobody will clear. mt7921_pci_shutdown() and mt7925_pci_shutdown() reuse the remove path, so this is hit on every reboot, poweroff and module unload. It is silent: the stuck task keeps sleeping and rescheduling, so neither the hung task detector nor the lockup detectors fire, and the last line on the console is "systemd-shutdown[1]: Rebooting." task:modprobe state:D stack:25720 pid:7954 tgid:7954 Call Trace: __schedule+0x11b8/0x26d0 schedule+0xe7/0x2f0 schedule_hrtimeout_range_clock+0x218/0x330 usleep_range_state+0x133/0x1b0 napi_disable_locked+0x37d/0x5f0 napi_disable+0x43/0x80 mt76_dma_cleanup+0x2b4/0x860 [mt76] mt7921_pci_remove+0x17f/0x350 [mt7921e] pci_device_remove+0xb6/0x1e0 device_release_driver_internal+0x38d/0x540 driver_detach+0xd0/0x1b0 bus_remove_driver+0x127/0x2d0 pci_unregister_driver+0x2a/0x280 __do_sys_delete_module+0x36a/0x5b0 do_syscall_64+0x11c/0x6d0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Dropping the two driver-side loops instead was tried and rejected: with them gone, the RX poll can reach mt76_token_release() via PKT_TYPE_TXRX_NOTIFY and mt7921_mac_tx_free() while mt76_connac2_tx_token_put() is running idr_destroy(&dev->token) outside token_lock, which is a use-after-free rather than a hang [1]. Revert for now, so that reboot, poweroff and module unload work again. The WARNs on mt7915e are a less severe problem than an unbootable machine, and fixing them belongs in the drivers that delete the NAPI instances, where each one can pick a point that is safe for its own teardown order, rather than in the shared mt76_dma_cleanup(). [ This is the "landing soonish" known regression fix mentioned in the previous networking merge commit - Linus ] Reported-by: Bert Karwatzki Closes: https://lore.kernel.org/all/20260724151419.26014-1-spasswolf@web.de/ Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221818 Link: https://lore.kernel.org/all/20260730050428.GA73812@sol/ [1] Signed-off-by: Mikhail Gavrilov Acked-by: Nicolas Cavallari Fixes: 13b7e6a96a00 ("wifi: mt76: Disable napi when removing device") Tested-by: Devin Wittmayer Signed-off-by: Linus Torvalds --- drivers/net/wireless/mediatek/mt76/dma.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index 322041859217..f8c2fe5f2f58 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -1189,10 +1189,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev) mt76_for_each_q_rx(dev, i) { struct mt76_queue *q = &dev->q_rx[i]; - if (!mt76_queue_is_wed_rro(q)) { - napi_disable(&dev->napi[i]); - netif_napi_del(&dev->napi[i]); - } + netif_napi_del(&dev->napi[i]); mt76_dma_rx_cleanup(dev, q); page_pool_destroy(q->page_pool); -- 2.47.3