* [REGRESSION] xhci: 3x descriptor timeout behind a vanished hub since 7.3
@ 2026-10-23 13:26 Diogo Chaves
2026-10-23 14:33 ` Mathias Nyman
0 siblings, 1 reply; 3+ messages in thread
From: Diogo Chaves @ 2026-10-23 13:26 UTC (permalink / raw)
To: Mathias Nyman; +Cc: Greg Kroah-Hartman, linux-usb, regressions
Hi Mathias,
This is my first report to linux-usb, so please tell me if something
is missing or belongs somewhere else.
Since 7.3, every time my monitor wakes up, my keyboard and mouse take
about 15 s longer to come back. The cause is a stall in usbcore's
enumeration of a device behind the monitor's USB hub, when that hub
drops while its child is being set up. Reverting
7e0ef4332ed9 ("xhci: avoid xHC endpoint changes after disconnect or link error.")
042aad8d0db6 ("xhci: prevent endpoint recovery after roothub disconnect")
on top of v7.3 makes the stall go away (A/B below).
Setup
-----
- xHC: ASMedia ASM4242 USB 3.2 xHCI [1b21:2426] (the board's USB4
controller), bus 1.
- On its USB-C port: a monitor with a Genesys Logic USB 2.1 hub
[05e3:0610] (1-1). Behind it, two Logitech receivers: [046d:c548]
on 1-1.1 and [046d:c547] on 1-1.2.
- On every wake, the monitor's firmware drops and re-adds that hub three
times in about 6 s. This has always happened. The last drop often
arrives just as hub_wq starts enumerating 1-1.1.
What happens
------------
In this race, 7.3 logs `usb 1-1.1: new full-speed USB device`, then
nothing, until `usb 1-1-port1: attempt power cycle` 3 x
initial_descriptor_timeout later (15 s with the default 5000 ms).
Before the series, the power cycle came within milliseconds.
A/B test, same machine, same config (the distro config trimmed with
localmodconfig), usbcore.initial_descriptor_timeout=1000 to shorten
the runs, monitor woken three times per boot plus the wake at boot.
Time from `usb 1-1.1: new full-speed` to `usb 1-1-port1: attempt power
cycle`:
v7.3 0.1*, 3.1, 3.1, 3.1 s
v7.3 + revert 7e0ef4332ed9 + 042aad8d0db6 0.03, 0.03, 0.03, 0.03 s
* at boot, on v7.3, the hub was gone before the descriptor read went
out (`cannot reset (err = -71)`).
Time from the first drop to both receivers working again: 11.2-11.3 s
on v7.3, 5.9-8.2 s with the revert. The rest of that time is the
monitor's own three resets.
On v7.3, one boot also hit the same thing one step later. The hub went
away after 1-1.2 had its address, and the full device descriptor read
then waited out USB_CTRL_GET_TIMEOUT:
08:56:10.097376 usb 1-1.2: new full-speed USB device number 12 using xhci_hcd
08:56:10.282395 usb 1-1: USB disconnect, device number 10
08:56:15.720384 usb 1-1.2: device descriptor read/all, error -110
08:56:15.723375 usb 1-1-port2: attempt power cycle
Trace
-----
The trace below was taken with xhci-hcd trace events and hub.c dynamic
debug, on a distro 7.2.8 kernel that carries this series as a backport
(I saw the same stall there first; plain v7.3 behaves the same, as
above). initial_descriptor_timeout=1000. Slot 104 is 1-1.1, behind
slot 103, the hub. Excerpt, CLOCK_MONOTONIC:
754.760938 xhci_handle_port_status: port 1-1: 0x000202a0 Speed=0 Link=RxDetect PP CSC
(the hub is gone)
754.807016 Address Device Command (BSR), slot 104
754.833730 xhci_urb_enqueue: 1-1.1 ep0 GET_DESCRIPTOR(DEVICE, 64), slot 104
754.833732 xhci_ring_ep_doorbell: slot 104 ep0in
(1st try, rung)
754.833755 xhci_handle_transfer: CTRL Setup Stage, error event
(fails at once; no giveback)
755.861009 xhci_urb_dequeue, Cancel URB, giveback
(usbcore's timeout, 1.03 s later)
755.861037 xhci_urb_enqueue, 3 TRBs queued, no doorbell
(2nd try, never sent)
756.886018 dequeue / giveback (timeout)
756.886054 xhci_urb_enqueue, 3 TRBs queued, no doorbell
(3rd try, never sent)
757.910008 dequeue / giveback (timeout), Disable Slot 104
(then hub.c: "attempt power cycle")
A possible explanation, from reading v7.3's xhci-ring.c with the
assistant mentioned at the end (I can't vouch for this part myself, so
please take it as a lead, not a diagnosis): the Setup stage error reaches
finish_td(), which calls xhci_handle_halted_endpoint() and returns,
expecting that function to have put the TD on the cancelled list
("xhci_handle_halted_endpoint marked td cancelled"). But
xhci_handle_halted_endpoint() now returns early with -ENODEV when
!rhub_port->connected, after setting EP_DROP_PENDING. The TD is neither
cancelled nor given back, so the URB sits until usbcore's own timeout
cancels it. Then usbcore retries. xhci_urb_enqueue() accepts the new
URBs, but xhci_ring_ep_doorbell() skips EP_DROP_PENDING, so each retry
also waits out the full timeout. Before the series, a disconnect went
through the endpoint reset path and the URB came back with an error at
once.
That is harmless for a device that is really leaving, but here it hits
every control transfer in flight, or queued, while the parent hub
drops. During enumeration, that is up to three tries of the initial
descriptor read, or one 5 s read/all.
Perhaps the early-return path should give the TD back with an error,
and URBs submitted to an EP_DROP_PENDING endpoint should fail at once.
I haven't tried either. I also haven't bisected between the two
commits; I only tested reverting both. I'm glad to test patches on this
machine; it reproduces on every monitor wake.
#regzbot introduced: 042aad8d0db6
Tools: I used an AI coding assistant (Claude Code) to capture and read
the trace, build the test kernels, read the xHCI code, and draft this
report. I checked the A/B measurements and the log lines against my
own journal; the code reading above is the assistant's, and I don't
know the xHCI code well enough to confirm it. I'm happy to run more
tests or take a trace with whatever you'd like enabled.
Thanks for looking at this, and for your work on xHCI.
Diogo Chaves
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [REGRESSION] xhci: 3x descriptor timeout behind a vanished hub since 7.3
2026-10-23 13:26 [REGRESSION] xhci: 3x descriptor timeout behind a vanished hub since 7.3 Diogo Chaves
@ 2026-10-23 14:33 ` Mathias Nyman
2026-10-23 19:01 ` Diogo Chaves
0 siblings, 1 reply; 3+ messages in thread
From: Mathias Nyman @ 2026-10-23 14:33 UTC (permalink / raw)
To: Diogo Chaves, Mathias Nyman; +Cc: Greg Kroah-Hartman, linux-usb, regressions
Hi
On 10/23/26 16:26, Diogo Chaves wrote:
> Hi Mathias,
>
> This is my first report to linux-usb, so please tell me if something
> is missing or belongs somewhere else.
>
> Since 7.3, every time my monitor wakes up, my keyboard and mouse take
> about 15 s longer to come back. The cause is a stall in usbcore's
> enumeration of a device behind the monitor's USB hub, when that hub
> drops while its child is being set up. Reverting
>
> 7e0ef4332ed9 ("xhci: avoid xHC endpoint changes after disconnect or link error.")
> 042aad8d0db6 ("xhci: prevent endpoint recovery after roothub disconnect")
>
> on top of v7.3 makes the stall go away (A/B below).
>
> Setup
> -----
> - xHC: ASMedia ASM4242 USB 3.2 xHCI [1b21:2426] (the board's USB4
> controller), bus 1.
> - On its USB-C port: a monitor with a Genesys Logic USB 2.1 hub
> [05e3:0610] (1-1). Behind it, two Logitech receivers: [046d:c548]
> on 1-1.1 and [046d:c547] on 1-1.2.
> - On every wake, the monitor's firmware drops and re-adds that hub three
> times in about 6 s. This has always happened. The last drop often
> arrives just as hub_wq starts enumerating 1-1.1.
>
> What happens
> ------------
> In this race, 7.3 logs `usb 1-1.1: new full-speed USB device`, then
> nothing, until `usb 1-1-port1: attempt power cycle` 3 x
> initial_descriptor_timeout later (15 s with the default 5000 ms).
> Before the series, the power cycle came within milliseconds.
>
> A/B test, same machine, same config (the distro config trimmed with
> localmodconfig), usbcore.initial_descriptor_timeout=1000 to shorten
> the runs, monitor woken three times per boot plus the wake at boot.
> Time from `usb 1-1.1: new full-speed` to `usb 1-1-port1: attempt power
> cycle`:
>
> v7.3 0.1*, 3.1, 3.1, 3.1 s
> v7.3 + revert 7e0ef4332ed9 + 042aad8d0db6 0.03, 0.03, 0.03, 0.03 s
>
> * at boot, on v7.3, the hub was gone before the descriptor read went
> out (`cannot reset (err = -71)`).
>
> Time from the first drop to both receivers working again: 11.2-11.3 s
> on v7.3, 5.9-8.2 s with the revert. The rest of that time is the
> monitor's own three resets.
>
> On v7.3, one boot also hit the same thing one step later. The hub went
> away after 1-1.2 had its address, and the full device descriptor read
> then waited out USB_CTRL_GET_TIMEOUT:
>
> 08:56:10.097376 usb 1-1.2: new full-speed USB device number 12 using xhci_hcd
> 08:56:10.282395 usb 1-1: USB disconnect, device number 10
> 08:56:15.720384 usb 1-1.2: device descriptor read/all, error -110
> 08:56:15.723375 usb 1-1-port2: attempt power cycle
>
> Trace
> -----
> The trace below was taken with xhci-hcd trace events and hub.c dynamic
> debug, on a distro 7.2.8 kernel that carries this series as a backport
> (I saw the same stall there first; plain v7.3 behaves the same, as
> above). initial_descriptor_timeout=1000. Slot 104 is 1-1.1, behind
> slot 103, the hub. Excerpt, CLOCK_MONOTONIC:
>
> 754.760938 xhci_handle_port_status: port 1-1: 0x000202a0 Speed=0 Link=RxDetect PP CSC
> (the hub is gone)
> 754.807016 Address Device Command (BSR), slot 104
> 754.833730 xhci_urb_enqueue: 1-1.1 ep0 GET_DESCRIPTOR(DEVICE, 64), slot 104
> 754.833732 xhci_ring_ep_doorbell: slot 104 ep0in
> (1st try, rung)
> 754.833755 xhci_handle_transfer: CTRL Setup Stage, error event
> (fails at once; no giveback)
> 755.861009 xhci_urb_dequeue, Cancel URB, giveback
> (usbcore's timeout, 1.03 s later)
> 755.861037 xhci_urb_enqueue, 3 TRBs queued, no doorbell
> (2nd try, never sent)
> 756.886018 dequeue / giveback (timeout)
> 756.886054 xhci_urb_enqueue, 3 TRBs queued, no doorbell
> (3rd try, never sent)
> 757.910008 dequeue / giveback (timeout), Disable Slot 104
> (then hub.c: "attempt power cycle")
>
> A possible explanation, from reading v7.3's xhci-ring.c with the
> assistant mentioned at the end (I can't vouch for this part myself, so
> please take it as a lead, not a diagnosis): the Setup stage error reaches
> finish_td(), which calls xhci_handle_halted_endpoint() and returns,
> expecting that function to have put the TD on the cancelled list
> ("xhci_handle_halted_endpoint marked td cancelled"). But
> xhci_handle_halted_endpoint() now returns early with -ENODEV when
> !rhub_port->connected, after setting EP_DROP_PENDING. The TD is neither
> cancelled nor given back, so the URB sits until usbcore's own timeout
> cancels it. Then usbcore retries. xhci_urb_enqueue() accepts the new
> URBs, but xhci_ring_ep_doorbell() skips EP_DROP_PENDING, so each retry
> also waits out the full timeout. Before the series, a disconnect went
> through the endpoint reset path and the URB came back with an error at
> once.
This is very likely the case. This same issue was reported, and fixed in:
https://lore.kernel.org/linux-usb/20261013073825.17962-1-yiyu@yiyuzhou.io/
That patch is sitting in my for-usb-linus branch.
https://git.kernel.org/pub/scm/linux/kernel/git/mnyman/xhci.git for-usb-linus
https://git.kernel.org/pub/scm/linux/kernel/git/mnyman/xhci.git/log/?h=for-usb-linus
Does it fix your case?
I can add 'Tested-by: Diogo Chaves <diogochaves@me.com>' tag to the patch if you are able to test it.
Thanks
Mathias
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [REGRESSION] xhci: 3x descriptor timeout behind a vanished hub since 7.3
2026-10-23 14:33 ` Mathias Nyman
@ 2026-10-23 19:01 ` Diogo Chaves
0 siblings, 0 replies; 3+ messages in thread
From: Diogo Chaves @ 2026-10-23 19:01 UTC (permalink / raw)
To: Mathias Nyman; +Cc: Greg Kroah-Hartman, linux-usb, regressions, Yiyu Zhou
On 10/23/26 17:33, Mathias Nyman wrote:
> This is very likely the case. This same issue was reported, and fixed in:
>
> https://lore.kernel.org/linux-usb/20261013073825.17962-1-yiyu@yiyuzhou.io/
>
> Does it fix your case?
Yes, it does. I tested v7.3 + 1f36cc9fa949 ("xhci: give back all TDs
when skipping endpoint reset after disconnect") from your for-usb-linus,
with the same config and usbcore.initial_descriptor_timeout=1000 as
before. Time from `usb 1-1.1: new full-speed` to
`usb 1-1-port1: attempt power cycle`:
boot wake 1 wake 2 wake 3
v7.3 0.1 3.1 3.1 3.1 s
v7.3, both reverted 0.03 0.03 0.03 0.03 s
v7.3 + 1f36cc9fa949 0.03, 0.19* 0.03 0.03 0.03 s
* the race hit twice at boot. The second time, the hub went away
160 ms into 1-1.1's enumeration, and the port was power-cycled
31 ms after `usb 1-1: USB disconnect`.
There was no `error -110`, `error -71` or `cannot reset` in that boot.
Both receivers were back 5.9-8.5 s after the first drop, the same as
with the revert (5.9-8.2 s).
Tested-by: Diogo Chaves <diogochaves@me.com>
#regzbot fix: xhci: give back all TDs when skipping endpoint reset after disconnect
Thanks to you and Yiyu.
Diogo
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-23 19:01 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23 13:26 [REGRESSION] xhci: 3x descriptor timeout behind a vanished hub since 7.3 Diogo Chaves
2026-10-23 14:33 ` Mathias Nyman
2026-10-23 19:01 ` Diogo Chaves
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox