aboutsummaryrefslogtreecommitdiffstats
path: root/queue-6.6/xhci-fix-failure-to-detect-ring-expansion-need.patch
diff options
context:
space:
mode:
Diffstat (limited to 'queue-6.6/xhci-fix-failure-to-detect-ring-expansion-need.patch')
-rw-r--r--queue-6.6/xhci-fix-failure-to-detect-ring-expansion-need.patch60
1 files changed, 60 insertions, 0 deletions
diff --git a/queue-6.6/xhci-fix-failure-to-detect-ring-expansion-need.patch b/queue-6.6/xhci-fix-failure-to-detect-ring-expansion-need.patch
new file mode 100644
index 0000000000..260e8b1225
--- /dev/null
+++ b/queue-6.6/xhci-fix-failure-to-detect-ring-expansion-need.patch
@@ -0,0 +1,60 @@
+From b234c70fefa7532d34ebee104de64cc16f1b21e4 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Tue, 5 Mar 2024 15:23:12 +0200
+Subject: xhci: Fix failure to detect ring expansion need.
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit b234c70fefa7532d34ebee104de64cc16f1b21e4 upstream.
+
+Ring expansion checker may incorrectly assume a completely full ring
+is empty, missing the need for expansion.
+
+This is due to a special empty ring case where the dequeue ends up
+ahead of the enqueue pointer. This is seen when enqueued TRBs fill up
+exactly a segment, with enqueue then pointing to the end link TRB.
+Once those TRBs are handled the dequeue pointer will follow the link
+TRB and end up pointing to the first entry on the next segment, past
+the enqueue.
+
+This same enqueue - dequeue condition can be true if a ring is full,
+with enqueue ending on that last link TRB before the dequeue pointer
+on the next segment.
+
+This can be seen when queuing several ~510 small URBs via usbfs in
+one go before a single one is handled (i.e. dequeue not moved from first
+entry in segment).
+
+Expand the ring already when enqueue reaches the link TRB before the
+dequeue segment, instead of expanding it when enqueue moves into the
+dequeue segment.
+
+Reported-by: Chris Yokum <linux-usb@mail.totalphase.com>
+Closes: https://lore.kernel.org/all/949223224.833962.1709339266739.JavaMail.zimbra@totalphase.com
+Tested-by: Chris Yokum <linux-usb@mail.totalphase.com>
+Fixes: f5af638f0609 ("xhci: Fix transfer ring expansion size calculation")
+Cc: stable@vger.kernel.org # v6.5+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20240305132312.955171-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-ring.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -326,7 +326,13 @@ static unsigned int xhci_ring_expansion_
+ /* how many trbs will be queued past the enqueue segment? */
+ trbs_past_seg = enq_used + num_trbs - (TRBS_PER_SEGMENT - 1);
+
+- if (trbs_past_seg <= 0)
++ /*
++ * Consider expanding the ring already if num_trbs fills the current
++ * segment (i.e. trbs_past_seg == 0), not only when num_trbs goes into
++ * the next segment. Avoids confusing full ring with special empty ring
++ * case below
++ */
++ if (trbs_past_seg < 0)
+ return 0;
+
+ /* Empty ring special case, enqueue stuck on link trb while dequeue advanced */