From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>,
Jonathan Bell <jonathan@raspberrypi.com>,
Lukas Wunner <lukas@wunner.de>,
Mathias Nyman <mathias.nyman@linux.intel.com>
Subject: [PATCH 05/19] xhci: Use more than one Event Ring segment
Date: Thu, 19 Oct 2023 13:29:10 +0300 [thread overview]
Message-ID: <20231019102924.2797346-6-mathias.nyman@linux.intel.com> (raw)
In-Reply-To: <20231019102924.2797346-1-mathias.nyman@linux.intel.com>
From: Jonathan Bell <jonathan@raspberrypi.com>
Users have reported log spam created by "Event Ring Full" xHC event
TRBs. These are caused by interrupt latency in conjunction with a very
busy set of devices on the bus. The errors are benign, but throughput
will suffer as the xHC will pause processing of transfers until the
Event Ring is drained by the kernel.
Commit dc0ffbea5729 ("usb: host: xhci: update event ring dequeue pointer
on purpose") mitigated the issue by advancing the Event Ring Dequeue
Pointer already after half a segment has been processed. Nevertheless,
providing a larger Event Ring would be useful to cope with load peaks.
Expand the number of event TRB slots available by increasing the number
of Event Ring segments in the ERST.
Controllers have a hardware-defined limit as to the number of ERST
entries they can process, but with up to 32k it can be excessively high
(sec 5.3.4). So cap the actual number at 2 (configurable through the
ERST_MAX_SEGS macro), which seems like a reasonable quantity. It is
supported by any xHC because the limit in the HCSPARAMS2 register is
defined as a power of 2. Renesas uPD720201 and VIA VL805 controllers
do not support more than 2 ERST entries.
An alternative to increasing the number of Event Ring segments would be
an increase of the segment size. But that requires allocating multiple
contiguous pages, which may be impossible if memory is fragmented.
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-mem.c | 10 +++++++---
drivers/usb/host/xhci.h | 5 +++--
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 17c9942010c8..a8a8fc2cc4a5 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2235,14 +2235,18 @@ xhci_alloc_interrupter(struct xhci_hcd *xhci, gfp_t flags)
{
struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
struct xhci_interrupter *ir;
+ unsigned int num_segs;
int ret;
ir = kzalloc_node(sizeof(*ir), flags, dev_to_node(dev));
if (!ir)
return NULL;
- ir->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, 1, TYPE_EVENT,
- 0, flags);
+ num_segs = min_t(unsigned int, 1 << HCS_ERST_MAX(xhci->hcs_params2),
+ ERST_MAX_SEGS);
+
+ ir->event_ring = xhci_ring_alloc(xhci, num_segs, 1, TYPE_EVENT, 0,
+ flags);
if (!ir->event_ring) {
xhci_warn(xhci, "Failed to allocate interrupter event ring\n");
kfree(ir);
@@ -2278,7 +2282,7 @@ xhci_add_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir,
/* set ERST count with the number of entries in the segment table */
erst_size = readl(&ir->ir_set->erst_size);
erst_size &= ERST_SIZE_MASK;
- erst_size |= ERST_NUM_SEGS;
+ erst_size |= ir->event_ring->num_segs;
writel(erst_size, &ir->ir_set->erst_size);
erst_base = xhci_read_64(xhci, &ir->ir_set->erst_base);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 5ddca9280ec3..41820fd97c00 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1647,8 +1647,9 @@ struct urb_priv {
* Each segment table entry is 4*32bits long. 1K seems like an ok size:
* (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
* meaning 64 ring segments.
- * Initial allocated size of the ERST, in number of entries */
-#define ERST_NUM_SEGS 1
+ * Reasonable limit for number of Event Ring segments (spec allows 32k)
+ */
+#define ERST_MAX_SEGS 2
/* Poll every 60 seconds */
#define POLL_TIMEOUT 60
/* Stop endpoint command timeout (secs) for URB cancellation watchdog timer */
--
2.25.1
next prev parent reply other threads:[~2023-10-19 10:28 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-19 10:29 [PATCH 00/19] xhci features for usb-next Mathias Nyman
2023-10-19 10:29 ` [PATCH 01/19] xhci: pass port structure to tracing instead of port number Mathias Nyman
2023-10-19 10:29 ` [PATCH 02/19] xhci: Add busnumber to port tracing Mathias Nyman
2023-10-19 10:29 ` [PATCH 03/19] xhci: expand next_trb() helper to support more ring types Mathias Nyman
2023-10-19 10:29 ` [PATCH 04/19] xhci: Set DESI bits in ERDP register correctly Mathias Nyman
2023-10-19 10:29 ` Mathias Nyman [this message]
2023-10-19 10:29 ` [PATCH 06/19] xhci: Adjust segment numbers after ring expansion Mathias Nyman
2023-10-19 10:29 ` [PATCH 07/19] xhci: Update last segment pointer after Event Ring expansion Mathias Nyman
2023-10-19 10:29 ` [PATCH 08/19] xhci: Expose segment numbers in debugfs Mathias Nyman
2023-10-19 10:29 ` [PATCH 09/19] xhci: Clean up ERST_PTR_MASK inversion Mathias Nyman
2023-10-19 10:29 ` [PATCH 10/19] xhci: Clean up stale comment on ERST_SIZE macro Mathias Nyman
2023-10-19 10:29 ` [PATCH 11/19] xhci: Clean up xhci_{alloc,free}_erst() declarations Mathias Nyman
2023-10-19 10:29 ` [PATCH 12/19] xhci: simplify event ring dequeue tracking for transfer events Mathias Nyman
2023-10-19 10:29 ` [PATCH 13/19] xhci: Simplify event ring dequeue pointer update for port change events Mathias Nyman
2023-10-19 10:29 ` [PATCH 14/19] xhci: Loosen RPM as default policy to cover for AMD xHC 1.1 Mathias Nyman
2023-10-19 10:29 ` [PATCH 15/19] xhci: Enable RPM on controllers that support low-power states Mathias Nyman
2023-10-19 10:29 ` [PATCH 16/19] xhci: split free interrupter into separate remove and free parts Mathias Nyman
2023-10-19 10:29 ` [PATCH 17/19] usb: xhci: Implement xhci_handshake_check_state() helper Mathias Nyman
2023-10-19 10:29 ` [PATCH 18/19] usb: host: xhci-plat: fix possible kernel oops while resuming Mathias Nyman
2023-10-19 10:29 ` [PATCH 19/19] usb: host: xhci: Avoid XHCI resume delay if SSUSB device is not present Mathias Nyman
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=20231019102924.2797346-6-mathias.nyman@linux.intel.com \
--to=mathias.nyman@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=jonathan@raspberrypi.com \
--cc=linux-usb@vger.kernel.org \
--cc=lukas@wunner.de \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.