mt7925/mt792x: module unload + reboot/shutdown hang (rx NAPI double-disable; MT7927 MCU teardown reset storm)
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 68/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- c, linux
- Ambito
- networking, operating-systems
Direzione di ricerca
Inizia da mt7925/pci.c, mt7921/pci.c, dma.c, mt7925/mcu.c, mt792x_dma.c, mt792x_irq_handler e mt76_mcu_skb_send_and_get_msg(). Traccia la rimozione del dispositivo attraverso entrambi i percorsi di teardown e confronta le guardie MT76_REMOVED e bus_hung esistenti. Il lavoro è completo quando scaricamento, riavvio e arresto terminano senza deadlock NAPI o tempeste di reset, mentre lo scaricamento/ricaricamento preserva il comportamento del Wi-Fi.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
On an MT7927 (Filogic 380, PCI 14c3:7927) running kernel 7.0.0 with mt76 at
b2704cf, modprobe -r mt7925e reliably hangs: the modprobe task is stuck in
D state with the module refcount at -1 and cannot be killed. Because the PCI
.shutdown callback (mt7925_pci_shutdown) also calls mt7925_pci_remove(),
this hangs system reboot and shutdown too.
Bisecting the teardown turned up two independent bugs, both in the shared
mt792x/mt76 teardown path. Fixing only one just moves the hang to the other.
Environment
- Card: MediaTek MT7927 / Filogic 380,
14c3:7927, chip family MT6639 - Driver:
mt7925e - Kernel: 7.0.0 (bug 1 is relevant to any kernel >= 6.15 — see below)
- mt76:
b2704cf
Bug 1 — rx NAPI double-disable deadlock (also affects mt7921)
mt7925e_unregister_device() disables the rx NAPIs:
/* mt7925/pci.c */
mt76_unregister_device(&dev->mt76);
mt76_for_each_q_rx(&dev->mt76, i)
napi_disable(&dev->mt76.napi[i]);
then, later in the same teardown, mt792x_dma_cleanup() -> mt76_dma_cleanup()
disables the same rx NAPIs a second time:
/* dma.c, mt76_dma_cleanup() */
mt76_for_each_q_rx(dev, i) {
...
napi_disable(&dev->napi[i]);
netif_napi_del(&dev->napi[i]);
...
}
On kernels >= 6.15 napi_disable() leaves NAPI_STATE_SCHED set as the
"disabled" marker, so the second napi_disable() on an already-disabled NAPI
loops forever (nothing will ever clear SCHED). The stuck task:
napi_disable_locked
napi_disable
mt76_dma_cleanup [mt76]
mt792x_dma_cleanup [mt792x_lib]
mt7925_pci_remove [mt7925e]
pci_device_remove
device_release_driver_internal
driver_detach
pci_unregister_driver
mt7925_pci_driver_exit [mt7925e]
__do_sys_delete_module
mt7921e_unregister_device() (mt7921/pci.c) has the identical
mt76_for_each_q_rx napi_disable(&dev->mt76.napi[i]) loop, so mt7921 should hit
the same hang on >= 6.15 kernels.
Suggested fix: drop the redundant napi_disable() loop from
*_unregister_device() — mt76_dma_cleanup() already disables and deletes
those NAPIs.
Bug 2 — MT7927 MCU teardown timeout -> reset storm
With bug 1 worked around, teardown then hangs earlier, spamming:
mt7925e 0000:0a:00.0: Message 00020002 (seq 2) timeout
mt7925e 0000:0a:00.0: Message 00020008 (seq 3) timeout
mt7925e 0000:0a:00.0: Message 00020016 (seq 4) timeout
...
wlp10s0: failed to remove key (0, ...) from hardware (-110)
On the MT7927 the MCU stops responding once teardown begins, so every teardown
MCU command times out (~3 s). Worse, on timeout mt7925_mcu_parse_response()
kicks a device reset:
/* mt7925/mcu.c, mt7925_mcu_parse_response() */
if (!skb) {
dev_err(mdev->dev, "Message %08x (seq %d) timeout\n", cmd, seq);
mt792x_reset(mdev); /* queues reset_work */
return -ETIMEDOUT;
}
mt792x_reset() queues reset_work, which re-inits the device and sends more
MCU commands, which time out, which queue another reset — an unbounded
timeout -> reset -> timeout loop.
MT76_REMOVED is set at the very start of mt7925_pci_remove() and is already
honored in the DMA/IRQ paths (mt792x_dma.c, mt792x_irq_handler), but the MCU
send path does not check it, so teardown MCU commands are still issued and still
(slowly) time out.
Suggested fix (two parts):
- Honor
MT76_REMOVEDinmt76_mcu_skb_send_and_get_msg()— fail MCU sends
fast during teardown (mirrors the existingbus_hungguard right below it and
the DMA/IRQ paths). - Skip
mt792x_reset()inmt7925_mcu_parse_response()whenMT76_REMOVEDis
set — don't kick a reset while the device is being removed.
Result
With both fixed, modprobe -r mt7925e completes cleanly (~2 s) and
reboot/shutdown no longer hang; wifi is unaffected across unload/reload.
Working patches against b2704cf are here for reference:
https://github.com/ardor99/mt7927-wifi7-dkms/tree/main/patches — happy to send
these to the linux-wireless list as proper patches if that is preferred.
- Lingua principale
- C
- Stelle
- 895
- Fork
- 461
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di openwrt/mt76
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
-
MT76xx - WLAN leds doesn't work with the testing kernelForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
-
mt7925: Netgear A8000 (0846:9072) reports hw_path without WF0_5G, so 5 GHz band is never registeredAperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 22/100
Tutte le issue di openwrt/mt76
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno
-
SPIDevice selects an active-high device as soon as it is createdForse già presa @mikeysklar l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
adafruit/circuitpython#11869 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 78/100
gnif/LookingGlass#1352 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100