| From 90c56c8f52c912aa6e990e63d953b6dbccea7250 Mon Sep 17 00:00:00 2001 |
| From: Jonathan Bell <jonathan@raspberrypi.org> |
| Date: Tue, 13 Aug 2019 15:53:29 +0100 |
| Subject: [PATCH] xhci: Use more event ring segment table entries |
| |
| 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. 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, so make the actual number in use |
| min(ERST_MAX_SEGS, hw_max). |
| |
| Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org> |
| --- |
| drivers/usb/host/xhci-mem.c | 8 +++++--- |
| drivers/usb/host/xhci.h | 4 ++-- |
| 2 files changed, 7 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/usb/host/xhci-mem.c |
| +++ b/drivers/usb/host/xhci-mem.c |
| @@ -2522,9 +2522,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, |
| * Event ring setup: Allocate a normal ring, but also setup |
| * the event ring segment table (ERST). Section 4.9.3. |
| */ |
| + val2 = 1 << HCS_ERST_MAX(xhci->hcs_params2); |
| + val2 = min_t(unsigned int, ERST_MAX_SEGS, val2); |
| xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Allocating event ring"); |
| - xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, 1, TYPE_EVENT, |
| - 0, flags); |
| + xhci->event_ring = xhci_ring_alloc(xhci, val2, 1, TYPE_EVENT, |
| + 0, flags); |
| if (!xhci->event_ring) |
| goto fail; |
| if (xhci_check_trb_in_td_math(xhci) < 0) |
| @@ -2537,7 +2539,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, |
| /* set ERST count with the number of entries in the segment table */ |
| val = readl(&xhci->ir_set->erst_size); |
| val &= ERST_SIZE_MASK; |
| - val |= ERST_NUM_SEGS; |
| + val |= val2; |
| xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
| "// Write ERST size = %i to ir_set 0 (some bits preserved)", |
| val); |
| --- a/drivers/usb/host/xhci.h |
| +++ b/drivers/usb/host/xhci.h |
| @@ -1656,8 +1656,8 @@ 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 |
| + * Maximum number of segments in the ERST */ |
| +#define ERST_MAX_SEGS 8 |
| /* Initial allocated size of the ERST, in number of entries */ |
| #define ERST_SIZE 64 |
| /* Initial number of event segment rings allocated */ |