** Description changed:
[ Impact ]
- When an MT7921AU USB Wi-Fi dongle (e.g. 0e8d:7961) experiences communication
stalls (USB -110 ETIMEDOUT errors), mt792x_mac_work holds dev->mt76.mutex while
looping on register reads. When USB core detects the stall and triggers unbind,
mt792xu_disconnect calls mt76_unregister_device, which takes rtnl_lock and
calls mt7921_abort_roc.
+ When an MT7921AU/MT7925 USB wireless adapter (e.g. 0e8d:7961) experiences
communication stalls (USB -110 ETIMEDOUT errors on MT_MIB_SDR9 register reads),
mt792x_mac_work holds dev->mt76.mutex while looping on register reads. When USB
core detects the stall and triggers unbind, mt792xu_disconnect calls
mt76_unregister_device, which takes rtnl_lock and calls mt7921_abort_roc (or
mt7925_abort_roc).
mt7921_abort_roc then tries to acquire dev->mt76.mutex, which is already
- held by the stuck mac_work thread. This creates an ABBA deadlock between
- rtnl_lock and mt76.mutex.
+ held by the stuck mac_work thread. This creates an unrecoverable ABBA
+ deadlock between rtnl_lock and dev->mt76.mutex.
As a result:
- - mac_work waits on USB timeouts with mt76.mutex held.
- - mt792xu_disconnect waits for mt76.mutex under rtnl_lock.
+ - mac_work waits on USB timeouts with dev->mt76.mutex held.
+ - mt792xu_disconnect waits for dev->mt76.mutex under rtnl_lock.
- All network operations (NetworkManager, ip, dev_close) hang forever in D
state waiting for rtnl_lock.
- The system cannot power off or reboot cleanly without a hard reset.
[ Fix ]
- 1. In mt792xu_disconnect(), set MT76_REMOVED, MT76_RESET, and MT76_MCU_RESET
flags and wake pending waitqueues before calling mt76_unregister_device().
Setting MT76_REMOVED causes all pending and subsequent USB register requests to
fail immediately with -EIO instead of waiting for 3-second timeouts.
- 2. In mt792xu_disconnect(), synchronously cancel all workers (mac_work,
ps_work, wake_work, reset_work, init_work) prior to unregistration.
- 3. In mt7921_abort_roc() (and mt7925_abort_roc()), check if MT76_REMOVED is
set. If the device was removed, clear MT76_STATE_ROC and return 0 immediately
without taking dev->mt76.mutex.
+ 1. In mt792xu_disconnect(), set MT76_REMOVED, MT76_RESET, and MT76_MCU_RESET
immediately, wake MCU waitqueues, purge res_q, and cancel reset_work and
init_work FIRST, followed by mac_work, ps_work, and wake_work before invoking
mt76_unregister_device(). Setting MT76_REMOVED causes all pending and
subsequent USB register requests to fail immediately with -EIO instead of
blocking on 3-second timeouts.
+ 2. In mt7921_mac_reset_work() and mt7925_mac_reset_work(), check
MT76_REMOVED: if the device was disconnected, abort reset immediately and skip
waking queues or interface iterations on a dead adapter.
+ 3. In mt7921_abort_roc() and mt7925_abort_roc(), check if MT76_REMOVED is
set. If the device was removed, clear MT76_STATE_ROC and return 0 immediately
without waiting on dev->mt76.mutex or sending MCU commands over a dead bus.
+ 4. In mt7921_mcu_parse_response() and mt7925_mcu_parse_response(), suppress
timeout error logging and mt792x_reset() when MT76_MCU_RESET or MT76_REMOVED is
set, avoiding spurious teardown noise and preventing reset_work re-queueing
during unbind.
[ Test Plan ]
- 1. Boot kernel 7.0.0-31-generic with patched mt7921u / mt792x-usb modules.
+ 1. Boot kernel (e.g. 7.0.0-34-generic) with patched mt7921u / mt792x-usb
modules.
2. Insert MT7921AU USB Wi-Fi adapter (0e8d:7961) and connect to an AP.
- 3. Physically disconnect the USB adapter while network traffic is active, or
trigger bus reset while requests are pending.
+ 3. Physically disconnect the USB adapter while network traffic is active
(~750 pkt/s TX load).
4. Verify in dmesg:
- - Device disconnect completes cleanly without call traces.
+ - Device disconnect completes cleanly without call traces, WARNINGs, or
blocked tasks.
- rtnl_lock is not blocked; NetworkManager and ip link operate normally.
+ - Re-plugging the adapter re-probes cleanly and reconnects.
- System reboots and powers off cleanly without hanging in D state.
+ Real hardware verification performed on Dell Precision 3650
(7.0.0-34-generic):
+ - 2x rmmod/insmod cycles: MCU teardown noise reduced to 0 lines, 0 warnings.
+ - Unplug under active TX load (~750 pkt/s): clean teardown, only "USB
disconnect" and benign "tx urb failed: -71". Clean re-probe and reconnection on
replug.
+
[ Where problems could occur ]
- - If abort_roc returns early without taking mutex on device removal, any
cleanup that relied on mutex serialization must be safe. Since MT76_REMOVED is
set, hardware registers cannot be accessed anyway, so skipping mutex and
clearing local flag is safe.
- - Canceling works before unregistering prevents concurrent execution during
teardown, which is the desired behavior on unbind.
+ - If abort_roc returns early without taking mutex on device removal, any
cleanup that relied on mutex serialization must be safe. Since MT76_REMOVED is
set, hardware registers cannot be accessed anyway, so skipping mutex and
clearing local state flag is safe.
+ - Worker cancellations prior to unregistration prevent concurrent execution
during teardown, which is the desired behavior on unbind.
+ - Suppressing MCU timeout logs when MT76_REMOVED/MT76_MCU_RESET is set only
silences noise during expected teardown; genuine runtime MCU timeouts with no
flags set continue to log and trigger recovery reset as before.
[ Other Info ]
- Patch tested and compiled against linux-headers-7.0.0-31-generic on Ubuntu
26.04 (Resolute). Clean compile with 0 errors and 0 warnings.
+ Target: Ubuntu Resolute (26.04) and upstream linux-wireless.
+ Patch: Fix mt7921u/mt792xu USB disconnect deadlock on timeout v3 (Attachment
on Launchpad).
+ Verified on hardware by: Piotr Kalinski <[email protected]>
(Tested-by: Piotr Kalinski <[email protected]>).
--- [ Original Report ]
Dell Precision 3650 Tower, Ubuntu 26.04 dev kernel 7.0.0-31-generic.
Alfa AWUS036AXM (MT7921AU, USB ID 0e8d:7961).
Under heavy traffic or weak signal, the adapter disconnects and reconnects
rapidly. Eventually kernel dmesg shows:
[ 342.112004] mt7921u 1-2:1.0: Message 00000040 (seq 4) timeout
[ 345.184002] mt7921u 1-2:1.0: Message 00000040 (seq 5) timeout
[ 348.256011] mt7921u 1-2:1.0: Failed to get patch sem
[ 351.328008] mt7921u 1-2:1.0: hardware init failed
After that, NetworkManager stops responding. Running 'ip link' hangs
indefinitely in D state.
Rebooting hangs on 'A stop job is running for Network Manager' and requires
SysRq+B or power button.
SysRq-t output shows mt7921_abort_roc blocked waiting on mutex while held by
mac_work:
[ 420.100012] task:kworker/u16:3 blocked for more than 120 seconds.
[ 420.100020] Call Trace:
[ 420.100025] __schedule+0x345/0x890
[ 420.100030] schedule+0x5a/0xc0
[ 420.100035] schedule_preempt_disabled+0x18/0x30
[ 420.100040] __mutex_lock.isra.0+0x28a/0x4b0
[ 420.100045] mt7921_abort_roc+0x2d/0x80 [mt7921_common]
[ 420.100050] ieee80211_set_disassoc+0x62/0x90 [cfg80211]
[ 420.100055] mt76_unregister_device+0x48/0x90 [mt76]
[ 420.100060] mt792xu_disconnect+0x3c/0x70 [mt792x_usb]
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2167595
Title:
mt7921u: USB reset after -110 timeouts deadlocks in mt7921_abort_roc,
blocks rtnl_lock and shutdown
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2167595/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs