From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>,
Michal Pecio <michal.pecio@gmail.com>,
Pedro Fonseca <pedro@fonseca.com.pt>,
Mathias Nyman <mathias.nyman@intel.com>
Subject: [PATCH 03/14] usb: xhci: Unlock for command abort polling
Date: Fri, 9 Oct 2026 12:58:23 +0300 [thread overview]
Message-ID: <20261009095834.561578-4-mathias.nyman@linux.intel.com> (raw)
In-Reply-To: <20261009095834.561578-1-mathias.nyman@linux.intel.com>
From: Michal Pecio <michal.pecio@gmail.com>
xhci_abort_cmd_ring() requests abort, waits for the CRR bit to clear,
drops xhci->lock and waits for the Command Ring Stopped event.
The CRR wait timeout is 5 seconds as suggested by xHCI 4.6.1.2, which
means that if the xHC fails to complete the operation at all, we poll
with the lock held and IRQs disabled for several seconds. If any other
CPU tries to acquire the lock, it will spin likewise. IRQs get delays,
drivers log errors, tasks freeze, it's a mess.
So drop the lock earlier, before waiting for the CRR bit. It should be
safe - the sole caller sets cmd_ring_state to CMD_RING_STATE_ABORTED
before calling us, which will prevent others from ringing the command
doorbell and interfering with the abort. Queuing new commands during
this time poses no danger, and if the command we try to abort actually
completes concurrently, existing code already needs to deal with this.
And in my testing it does - it's trivial to trigger this on ASM1042,
where Address Device can't be aborted, but it completes as soon as the
offending device is unplugged, including during abort attempt.
Note that the lock still covers reinit_completion(), so it won't race
with complete() being called by the event handler. And works are not
reentrant, so another timeout can't expire while the lock is dropped.
We will configure timeout anew when restarting the ring.
One other difference is that now we also drop the lock if abort fails.
This too should be harmless. Commands queued during this time will be
released like any other pending commands. If the aborted command does
complete before we regain the lock, it's a waste, but not regression.
Reported-by: Pedro Fonseca <pedro@fonseca.com.pt>
Link: https://lore.kernel.org/linux-usb/16f65081-5a3c-4c30-9811-9017796a3373@fonseca.com.pt/
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
Signed-off-by: Mathias Nyman <mathias.nyman@intel.com>
---
drivers/usb/host/xhci-ring.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ec278a9f9540..82dd93c2afdd 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -494,7 +494,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
struct xhci_segment *new_seg = xhci->cmd_ring->deq_seg;
union xhci_trb *new_deq = xhci->cmd_ring->dequeue;
u64 crcr;
- int ret;
+ int ret, completed;
xhci_dbg(xhci, "Abort command ring\n");
@@ -521,25 +521,27 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
* In the future we should distinguish between -ENODEV and -ETIMEDOUT
* and try to recover a -ETIMEDOUT with a host controller reset.
*/
+ spin_unlock_irqrestore(&xhci->lock, flags);
ret = xhci_handshake(&xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
- if (ret < 0) {
- xhci_err(xhci, "Abort failed to stop command ring: %d\n", ret);
- xhci_halt(xhci);
- xhci_hc_died(xhci);
- return ret;
- }
/*
* Writing the CMD_RING_ABORT bit should cause a cmd completion event,
* however on some host hw the CMD_RING_RUNNING bit is correctly cleared
* but the completion event in never sent. Wait 2 secs (arbitrary
* number) to handle those cases after negation of CMD_RING_RUNNING.
*/
- spin_unlock_irqrestore(&xhci->lock, flags);
- ret = wait_for_completion_timeout(&xhci->cmd_ring_stop_completion,
+ if (ret >= 0)
+ completed = wait_for_completion_timeout(&xhci->cmd_ring_stop_completion,
msecs_to_jiffies(2000));
spin_lock_irqsave(&xhci->lock, flags);
- if (!ret) {
+
+ if (ret < 0) {
+ xhci_err(xhci, "Abort failed to stop command ring: %d\n", ret);
+ xhci_halt(xhci);
+ xhci_hc_died(xhci);
+ return ret;
+ }
+ if (!completed) {
xhci_dbg(xhci, "No stop event for abort, ring start fail?\n");
xhci_cleanup_command_queue(xhci);
} else {
--
2.43.0
next prev parent reply other threads:[~2026-10-09 9:58 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-09 9:58 [PATCH 00/14] xhci features and fixes for usb-next Mathias Nyman
2026-10-09 9:58 ` [PATCH 01/14] early: usb: xhci-dbc: Handle out of bounds xhci-xdbc capability Mathias Nyman
2026-10-09 10:11 ` sashiko-bot
2026-10-09 14:52 ` Mathias Nyman
2026-10-09 9:58 ` [PATCH 02/14] usb: xhci: return an error if the host is not halted Mathias Nyman
2026-10-09 10:13 ` sashiko-bot
2026-10-09 9:58 ` Mathias Nyman [this message]
2026-10-09 10:10 ` [PATCH 03/14] usb: xhci: Unlock for command abort polling sashiko-bot
2026-10-09 9:58 ` [PATCH 04/14] usb: xhci: fix typos in comments Mathias Nyman
2026-10-09 10:02 ` sashiko-bot
2026-10-09 9:58 ` [PATCH 05/14] xhci: check device notification type before forwarding wake event Mathias Nyman
2026-10-09 10:10 ` sashiko-bot
2026-10-09 9:58 ` [PATCH 06/14] xhci: dbc: lock the minor IDR on registration failure Mathias Nyman
2026-10-09 10:13 ` sashiko-bot
2026-10-09 10:51 ` Greg KH
2026-10-09 10:52 ` Greg KH
2026-10-09 11:16 ` Mathias Nyman
2026-10-09 11:23 ` Greg KH
2026-10-09 9:58 ` [PATCH 07/14] usb: xhci: sideband: fix ring sg table for sub-page TRB segments Mathias Nyman
2026-10-09 10:15 ` sashiko-bot
2026-10-09 13:35 ` Mathias Nyman
2026-10-09 9:58 ` [PATCH 08/14] usb: xhci-pci: Add TUSB73x0 definitions Mathias Nyman
2026-10-09 10:07 ` sashiko-bot
2026-10-09 12:15 ` Mathias Nyman
2026-10-09 9:58 ` [PATCH 09/14] usb: xhci: Guarantee URB giveback on Ring Underrun/Overrun Mathias Nyman
2026-10-09 10:11 ` sashiko-bot
2026-10-09 9:58 ` [PATCH 10/14] usb: xhci: Don't set the skip flag on non-isoc endpoints Mathias Nyman
2026-10-09 10:16 ` sashiko-bot
2026-10-09 12:06 ` Mathias Nyman
2026-10-09 9:58 ` [PATCH 11/14] usb: xhci: Shorten the TD skipping loop Mathias Nyman
2026-10-09 10:06 ` sashiko-bot
2026-10-09 9:58 ` [PATCH 12/14] usb: xhci: Rework and improve the TD matching and skipping logic Mathias Nyman
2026-10-09 10:15 ` sashiko-bot
2026-10-09 9:58 ` [PATCH 13/14] usb: xhci: Fix bounce buffer overflow Mathias Nyman
2026-10-09 10:15 ` sashiko-bot
2026-10-09 9:58 ` [PATCH 14/14] xhci: Prevent invalid vdev dereference during sideband unregister Mathias Nyman
2026-10-09 10:12 ` sashiko-bot
2026-10-09 10:50 ` [PATCH 00/14] xhci features and fixes for usb-next Greg KH
2026-10-09 11:00 ` Mathias Nyman
2026-10-09 12:23 ` Michal Pecio
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=20261009095834.561578-4-mathias.nyman@linux.intel.com \
--to=mathias.nyman@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@intel.com \
--cc=michal.pecio@gmail.com \
--cc=pedro@fonseca.com.pt \
/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