Linux USB
 help / color / mirror / Atom feed
* [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

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