[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251022100029.14189-1-uttkarsh.aggarwal@oss.qualcomm.com>
Date: Wed, 22 Oct 2025 15:30:29 +0530
From: Uttkarsh Aggarwal <uttkarsh.aggarwal@....qualcomm.com>
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Mathias Nyman <mathias.nyman@...el.com>
Cc: linux-usb@...r.kernel.org, linux-kernel@...r.kernel.org,
wesley.cheng@....qualcomm.com,
Uttkarsh Aggarwal <uttkarsh.aggarwal@....qualcomm.com>
Subject: [RFC PATCH] usb: host: xhci: Release spinlock before xhci_handshake in command ring abort
Currently xhci_handshake is a polling loop that waits for change of state.
If this loop is executed while holding a spinlock with IRQs disabled, it
can block interrupts for up to 5 seconds.
To prevent prolonged IRQ disable durations that may lead to watchdog
timeouts, release the spinlock before invoking xhci_handshake() in
xhci_abort_cmd_ring().
The spinlock is reacquired after the handshake to continue with controller
halt and recovery if needed.
Signed-off-by: Uttkarsh Aggarwal <uttkarsh.aggarwal@....qualcomm.com>
---
drivers/usb/host/xhci-ring.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 8e209aa33ea7..fca4df6a4699 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -518,10 +518,12 @@ 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);
+ spin_lock_irqsave(&xhci->lock, flags);
xhci_halt(xhci);
xhci_hc_died(xhci);
return ret;
@@ -532,7 +534,6 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
* 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,
msecs_to_jiffies(2000));
spin_lock_irqsave(&xhci->lock, flags);
--
2.17.1
Powered by blists - more mailing lists