Re: [PATCH v2] usb: uas: quiesce SCSI before stopping endpoints on unbind
From: Jiayi Li
Date: Tue Sep 22 2026 - 06:07:12 EST
> [Severity: High]
> Will moving scsi_remove_host() before devinfo->resetting = 1 and
> uas_zap_pending() cause a 30-second hang and 100% CPU livelock on
> physical unplug?
>
> On physical unplug, usbcore detects the disconnect and calls
> usb_disable_device(), which kills all active URBs with status -ESHUTDOWN
> before calling uas_disconnect().
>
> scsi_remove_host() synchronously waits for all in-flight SCSI commands to
> complete. Because the commands are stuck in-flight until uas_zap_pending()
> forcefully completes them, scsi_remove_host() will block indefinitely.
Thanks for the review.
I tested this case with v2 and can reproduce the approximately
30-second timeout by physically unplugging the device while UAS
commands are still in flight. I have not confirmed the reported
100% CPU livelock.
For a driver-only unbind, soft_unbind keeps the endpoints available
and the new ordering works as intended.
For a physical disconnect, however, the status URB completes with
-ESHUTDOWN before uas_disconnect() gets to drain the SCSI host.
uas_stat_cmplt() takes the error path in this case and does not clear
COMMAND_INFLIGHT.
With the v2 ordering, the sequence is therefore roughly:
status URB -> -ESHUTDOWN
-> COMMAND_INFLIGHT remains set
-> scsi_remove_host()
-> outstanding command cannot reach scsi_done()
-> SCSI timeout
The existing disconnect ordering avoids this because
uas_zap_pending() runs before scsi_remove_host() and explicitly clears
COMMAND_INFLIGHT after the status URBs have been killed.
Would it make more sense to retain the original kill/zap-first ordering
for a physical disconnect, while keeping scsi_remove_host()-first for
a soft unbind?
I understand Alan's earlier point that USB_STATE_NOTATTACHED alone has
a race window, so if separate handling is appropriate, the remaining
question would be how to distinguish these cases reliably.
Thanks,
Jiayi