Linux USB
 help / color / mirror / Atom feed
From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: Michal Pecio <michal.pecio@gmail.com>, Yiyu Zhou <yiyu@yiyuzhou.io>
Cc: mathias.nyman@intel.com, gregkh@linuxfoundation.org,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] xhci: give back halted TD when skipping endpoint reset after disconnect
Date: Mon, 12 Oct 2026 19:22:47 +0300	[thread overview]
Message-ID: <330c34fd-1d1c-44e8-b949-ad2f5fb51f00@linux.intel.com> (raw)
In-Reply-To: <20261012104122.0af52938.michal.pecio@gmail.com>

On 10/12/26 11:41, Michal Pecio wrote:
> On Fri,  9 Oct 2026 23:42:19 -0700, Yiyu Zhou wrote:
>> Commit 042aad8d0db6 ("xhci: prevent endpoint recovery after roothub
>> disconnect") makes xhci_handle_halted_endpoint() return early when the
>> root port is disconnected, and commit 7e0ef4332ed9 ("xhci: avoid xHC
>> endpoint changes after disconnect or link error.") also sets
>> EP_DROP_PENDING there, which keeps the doorbell from being rung until
>> the device is reset.
>>
>> The callers rely on xhci_handle_halted_endpoint() to take over the
>> halted TD.  For example, finish_td() returns right after calling it,
>> expecting the TD to be given back once the Reset Endpoint command
>> completes.  With the early return, nobody gives the TD back.  Its URB
>> stays pending until the submitter times out and unlinks it.  Every URB
>> queued on the endpoint afterwards never starts, because the doorbell
>> is blocked, and also has to time out.
> 
> Before 7.3 there was a similar device flag VDEV_PORT_ERROR which stuck
> until the device is reset or deleted. It only applied to USB3 devices.
> URBs were left hanging, but nobody cared, because disconnect() handler
> of the class driver would unlink them.
>   
>> Devices that disconnect and reconnect themselves during enumeration hit
>> this.  A PFU HHKB Professional HYBRID Type-S keyboard (04fe:0021) drops
>> off the bus about 300 ms after its first enumeration, while usbhid is
>> still probing its third interface.  The probe runs in hub_wq, so the
>> disconnect is not handled until the probe returns.
> 
> But probe breaks this scheme, it seems we do have no choice but to stop
> being lazy and give back the URB right there.
> 
> Regression occurred when the mechanism has been generalized to USB2 by
> also looking at the PORTSC.CCS bit, even though the problems it tries
> to solve have been unique to USB3 so far.
> 
> But this change seems sensible, because a USB3 port may autonomously
> exit the Error state to Disconnected on receiver termination loss, see
> xHCI 4.19.1.2.6, and PLS changes to RxDetect. It may even reach Enabled
> before software intervention; seems we should look at PORTSC.CSC too.
> 
> (On a USB2 port, like this keyboard uses, such race doesn't exist).
> 
> And since xhci_irq() clears these per-port flags when USB3 link comes
> back, there is no guarantee that the permanent EP_DROP_PENDING state
> will be latched on the lost device. Whether the HW bugs caused by link
> loss will still be happening on the "new" link is unclear; I only know
> about Renesas: it doesn't mind and actually recovers on reconnection.
> But the device is reset, which may or may not catch some xHC off guard.
> 
> Not sure if going back to a sticky per-device bit wouldn't be better.
> One downside is that we need to flag all affected devices, which means
> a loop in IRQ. Not great, but there is never more than 255 devices, so
> maybe a few microseconds at worst. Likely not enough latency to break
> anything, and it saves some repetitive checks in other places.
> 
> I could cook up a patch like that, I think it would make things easier,
> as there is no need for those very similar checks in urb_enqueue() for
> example, as seen below. But let's see what Mathias thinks.
> 

The solution in this patch seems reasonable to me.
It's simple enough and should solve this, and similar cases.

We should probably give back all TDs of the halted endpoint,
not just the one we halted on.

Agree with the minor changes you suggested to this patch.

-Mathias



  reply	other threads:[~2026-10-12 16:22 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-10  6:42 [PATCH] xhci: give back halted TD when skipping endpoint reset after disconnect Yiyu Zhou
2026-10-10  7:06 ` sashiko-bot
2026-10-10  7:17 ` Yiyu Zhou
2026-10-12  8:41 ` Michal Pecio
2026-10-12 16:22   ` Mathias Nyman [this message]
2026-10-13  7:37     ` [PATCH v2] xhci: give back all TDs " Yiyu Zhou
2026-10-13  7:56       ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=330c34fd-1d1c-44e8-b949-ad2f5fb51f00@linux.intel.com \
    --to=mathias.nyman@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=michal.pecio@gmail.com \
    --cc=yiyu@yiyuzhou.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox