* [PATCH] usb: xhci: Tear down host on Reset Endpoint and Set TR Dequeue timeout
@ 2026-11-04 1:27 Ambareesh Balaji
2026-11-04 1:38 ` sashiko-bot
2026-11-04 9:15 ` Michal Pecio
0 siblings, 2 replies; 5+ messages in thread
From: Ambareesh Balaji @ 2026-11-04 1:27 UTC (permalink / raw)
To: mathias.nyman; +Cc: gregkh, linux-usb, linux-kernel, Ambareesh Balaji
When a command times out, xhci_handle_command_timeout() aborts the
command ring. The aborted command is turned into a No-Op TRB, so its
completion is handled as a No-Op and the command's own handler never
runs.
A timed out Stop Endpoint command already halts the host and tears it
down. Reset Endpoint and Set TR Dequeue Pointer timeouts are not
handled, so the endpoint stays halted (EP_HALTED or SET_DEQ_PENDING)
and its cancelled TDs are never given back. A driver waiting for those
URBs, such as usb_kill_urb() during unbind, then waits forever.
Reset Endpoint and Set TR Dequeue Pointer change endpoint state in the
host controller only and never talk to the device, so a timeout means
the host controller is not responding, as with Stop Endpoint. Handle
them the same way: halt the host and give back all URBs with
xhci_hc_died(). The endpoint state flags are not cleared here, because
the endpoint handlers and URB dequeue check XHCI_STATE_DYING first.
The timeout was reproduced on an AMD xHCI controller passed through to a
QEMU/KVM guest. An endpoint halt was set on a usbhid interrupt IN endpoint
and the doorbell of the Set TR Dequeue Pointer command queued by the
usbhid unbind was suppressed with a kprobe, to emulate a host that does
not answer the command. Without this change the unbind blocks forever in
usb_kill_urb(). With it the command times out, the host is torn down and
the unbind completes. Normal unbind and rebind of the same device is
unaffected.
Fixes: c311e391a7ef ("xhci: rework command timeout and cancellation,")
Signed-off-by: Ambareesh Balaji <ambareeshbalaji@gmail.com>
---
drivers/usb/host/xhci-ring.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index c23434001e9c..b03ff184c074 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1755,20 +1755,23 @@ void xhci_handle_command_timeout(struct work_struct *work)
usbsts = readl(&xhci->op_regs->status);
xhci_dbg(xhci, "Command timeout, USBSTS:%s\n", xhci_decode_usbsts(str, usbsts));
- /* Bail out and tear down xhci if a stop endpoint command failed */
- if (TRB_FIELD_TO_TYPE(cmd_field3) == TRB_STOP_RING) {
- struct xhci_virt_ep *ep;
-
- xhci_warn(xhci, "xHCI host not responding to stop endpoint command\n");
-
- ep = xhci_get_virt_ep(xhci, TRB_TO_SLOT_ID(cmd_field3),
- TRB_TO_EP_INDEX(cmd_field3));
- if (ep)
- ep->ep_state &= ~EP_STOP_CMD_PENDING;
+ /*
+ * Bail out and tear down xhci if an endpoint command failed. An aborted
+ * command is turned into a No-Op, so its handler never runs and the
+ * cancelled TDs of the endpoint are not given back.
+ */
+ switch (TRB_FIELD_TO_TYPE(cmd_field3)) {
+ case TRB_STOP_RING:
+ case TRB_RESET_EP:
+ case TRB_SET_DEQ:
+ xhci_warn(xhci, "xHCI host not responding to %s\n",
+ xhci_trb_type_string(TRB_FIELD_TO_TYPE(cmd_field3)));
xhci_halt(xhci);
xhci_hc_died(xhci);
goto time_out_completed;
+ default:
+ break;
}
/* mark this command to be cancelled */
--
2.56.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] usb: xhci: Tear down host on Reset Endpoint and Set TR Dequeue timeout
2026-11-04 1:27 [PATCH] usb: xhci: Tear down host on Reset Endpoint and Set TR Dequeue timeout Ambareesh Balaji
@ 2026-11-04 1:38 ` sashiko-bot
2026-11-04 9:15 ` Michal Pecio
1 sibling, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-11-04 1:38 UTC (permalink / raw)
To: Ambareesh Balaji; +Cc: linux-usb
> When a command times out, xhci_handle_command_timeout() aborts the
> command ring. The aborted command is turned into a No-Op TRB, so its
> completion is handled as a No-Op and the command's own handler never
> runs.
>
> A timed out Stop Endpoint command already halts the host and tears it
> down. Reset Endpoint and Set TR Dequeue Pointer timeouts are not
> handled, so the endpoint stays halted (EP_HALTED or SET_DEQ_PENDING)
> and its cancelled TDs are never given back. A driver waiting for those
> URBs, such as usb_kill_urb() during unbind, then waits forever.
>
> Reset Endpoint and Set TR Dequeue Pointer change endpoint state in the
> host controller only and never talk to the device, so a timeout means
> the host controller is not responding, as with Stop Endpoint. Handle
> them the same way: halt the host and give back all URBs with
> xhci_hc_died(). The endpoint state flags are not cleared here, because
> the endpoint handlers and URB dequeue check XHCI_STATE_DYING first.
>
> The timeout was reproduced on an AMD xHCI controller passed through to a
> QEMU/KVM guest. An endpoint halt was set on a usbhid interrupt IN endpoint
> and the doorbell of the Set TR Dequeue Pointer command queued by the
> usbhid unbind was suppressed with a kprobe, to emulate a host that does
> not answer the command. Without this change the unbind blocks forever in
> usb_kill_urb(). With it the command times out, the host is torn down and
> the unbind completes. Normal unbind and rebind of the same device is
> unaffected.
>
> Fixes: c311e391a7ef ("xhci: rework command timeout and cancellation,")
> Signed-off-by: Ambareesh Balaji <ambareeshbalaji@gmail.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104012725.147741-1-ambareeshbalaji@gmail.com?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] usb: xhci: Tear down host on Reset Endpoint and Set TR Dequeue timeout
2026-11-04 1:27 [PATCH] usb: xhci: Tear down host on Reset Endpoint and Set TR Dequeue timeout Ambareesh Balaji
2026-11-04 1:38 ` sashiko-bot
@ 2026-11-04 9:15 ` Michal Pecio
2026-11-04 9:36 ` Ambareesh Balaji
1 sibling, 1 reply; 5+ messages in thread
From: Michal Pecio @ 2026-11-04 9:15 UTC (permalink / raw)
To: Ambareesh Balaji; +Cc: mathias.nyman, gregkh, linux-usb, linux-kernel
On Wed, 4 Nov 2026 01:27:25 +0000, Ambareesh Balaji wrote:
> When a command times out, xhci_handle_command_timeout() aborts the
> command ring. The aborted command is turned into a No-Op TRB, so its
> completion is handled as a No-Op and the command's own handler never
> runs.
>
> A timed out Stop Endpoint command already halts the host and tears it
> down. Reset Endpoint and Set TR Dequeue Pointer timeouts are not
> handled, so the endpoint stays halted (EP_HALTED or SET_DEQ_PENDING)
> and its cancelled TDs are never given back. A driver waiting for those
> URBs, such as usb_kill_urb() during unbind, then waits forever.
>
> Reset Endpoint and Set TR Dequeue Pointer change endpoint state in the
> host controller only and never talk to the device, so a timeout means
> the host controller is not responding, as with Stop Endpoint. Handle
> them the same way: halt the host and give back all URBs with
> xhci_hc_died(). The endpoint state flags are not cleared here, because
> the endpoint handlers and URB dequeue check XHCI_STATE_DYING first.
>
> The timeout was reproduced on an AMD xHCI controller passed through to a
> QEMU/KVM guest. An endpoint halt was set on a usbhid interrupt IN endpoint
> and the doorbell of the Set TR Dequeue Pointer command queued by the
> usbhid unbind was suppressed with a kprobe, to emulate a host that does
> not answer the command. Without this change the unbind blocks forever in
> usb_kill_urb(). With it the command times out, the host is torn down and
> the unbind completes. Normal unbind and rebind of the same device is
> unaffected.
>
> Fixes: c311e391a7ef ("xhci: rework command timeout and cancellation,")
> Signed-off-by: Ambareesh Balaji <ambareeshbalaji@gmail.com>
If timeout of those commands is handled as poorly as you say it is
then it looks like nobody is actually running into those cases (or they
would have been reported), so it's not very urgent. But regression risk
is also low then.
I have long wondered if we shouldn't simply halt the HC on every
command timeout other than Address Device. Commands shouldn't be taking
5 seconds to complete. When they do, something unexpected must be going
on and it's unclear if the HC is still usable or capable of recovering
cleanly when we abort the command. (I recall that aborting Stop EP on
one old and dodgy HC leaves the endpoint in a bogus state).
I have been running with a local patch which turns command timeouts
into xhci_halt/xhci_hc_died and so far the only functional difference
I noticed is that the driver takes less time to "kill" hanged HCs.
Note that in practical workloads, there are usually many endpoints and
sooner or later somebody unlinks a URB and causes Stop EP timeout, so
we "kill" the HC anyway. I haven't seen cases when Reset EP or Set TR
Dequeue hang but other commands still work.
I could submit this patch for 7.5. It doesn't seem urgent and probably
doesn't deserve "Fixes" or "Cc:stable".
Regards,
Michal
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] usb: xhci: Tear down host on Reset Endpoint and Set TR Dequeue timeout
2026-11-04 9:15 ` Michal Pecio
@ 2026-11-04 9:36 ` Ambareesh Balaji
2026-11-04 9:50 ` Michal Pecio
0 siblings, 1 reply; 5+ messages in thread
From: Ambareesh Balaji @ 2026-11-04 9:36 UTC (permalink / raw)
To: Michal Pecio; +Cc: Mathias Nyman, Greg Kroah-Hartman, linux-usb, linux-kernel
Hi Michal,
Thanks for the review.
On Wed, 4 Nov 2026 10:15:06 +0100, Michal Pecio wrote:
> I have long wondered if we shouldn't simply halt the HC on every
> command timeout other than Address Device. Commands shouldn't be
> taking 5 seconds to complete. When they do, something unexpected
> must be going on and it's unclear if the HC is still usable or
> capable of recovering cleanly when we abort the command.
Your approach is better than mine, which only covers Reset Endpoint
and Set TR Dequeue Pointer. I am happy to drop my patch in favour of
yours for 7.5, and agree it should not have Fixes: or Cc: stable. I
will test your patch once it is posted.
> I haven't seen cases when Reset EP or Set TR Dequeue hang but other
> commands still work.
I can't show that these timeouts happen on real hardware yet. What I
have is:
1) A fault injection reproducer. On an AMD xHCI (1022:1587) passed
through to a QEMU guest, I halt a usbhid interrupt IN endpoint with a
real SET_FEATURE(ENDPOINT_HALT), then suppress the doorbell of the Set
TR Dequeue Pointer command queued by the usbhid unbind. Without a fix
the unbind blocks forever in usb_kill_urb(). With my patch the command
times out, the host is torn down and the unbind completes. Normal
unbind and rebind of the same device is unaffected. I can send the
injection module and test script if you want to run it against your
patch.
2) One real hang with the same symptom on the same controller type
(kernel 7.3.1, tainted by out-of-tree DKMS modules). After a Focusrite
Scarlett Solo logged "USB disconnect", usb_hub_wq stayed in D state
for over 4 minutes in usb_kill_urb(), called from
scarlett2_private_free() on the disconnect path. Nothing recovered it
and only a reboot helped. There was no "xHCI host not responding to
stop endpoint command" in the log.
Reset Endpoint and Set TR Dequeue Pointer timeouts are only reported
through xhci_dbg(), so the missing message does not rule them out,
but it does not confirm them either. I see USB audio hangs like this
once or twice a month. I have enabled xHCI dynamic debug and tracing
and will send what I capture if it happens again.
Regards,
Ambareesh
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] usb: xhci: Tear down host on Reset Endpoint and Set TR Dequeue timeout
2026-11-04 9:36 ` Ambareesh Balaji
@ 2026-11-04 9:50 ` Michal Pecio
0 siblings, 0 replies; 5+ messages in thread
From: Michal Pecio @ 2026-11-04 9:50 UTC (permalink / raw)
To: Ambareesh Balaji
Cc: Mathias Nyman, Greg Kroah-Hartman, linux-usb, linux-kernel
On Wed, 4 Nov 2026 09:36:08 +0000, Ambareesh Balaji wrote:
> 2) One real hang with the same symptom on the same controller type
> (kernel 7.3.1, tainted by out-of-tree DKMS modules). After a Focusrite
> Scarlett Solo logged "USB disconnect", usb_hub_wq stayed in D state
> for over 4 minutes in usb_kill_urb(), called from
> scarlett2_private_free() on the disconnect path. Nothing recovered it
> and only a reboot helped. There was no "xHCI host not responding to
> stop endpoint command" in the log.
>
> Reset Endpoint and Set TR Dequeue Pointer timeouts are only reported
> through xhci_dbg(), so the missing message does not rule them out,
> but it does not confirm them either. I see USB audio hangs like this
> once or twice a month. I have enabled xHCI dynamic debug and tracing
> and will send what I capture if it happens again.
If this happens on real HW then it's a different thing. Having logs
of this anomaly would surely help untangling what happens there.
Were you seeing these issues before 7.3? That release made changes to
the handling of URBs on disconnected devices, which caused some people
problems even in absence of host controller bugs.
Regards,
Michal
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-04 9:50 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 1:27 [PATCH] usb: xhci: Tear down host on Reset Endpoint and Set TR Dequeue timeout Ambareesh Balaji
2026-11-04 1:38 ` sashiko-bot
2026-11-04 9:15 ` Michal Pecio
2026-11-04 9:36 ` Ambareesh Balaji
2026-11-04 9:50 ` Michal Pecio
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox