Skip to content

Commit d8693fc

Browse files
author
Jonathan Bell
committed
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 <[email protected]>
1 parent 1f8e541 commit d8693fc

File tree

2 files changed

+11
-9
lines changed

2 files changed

+11
-9
lines changed

drivers/usb/host/xhci-mem.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2491,9 +2491,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
24912491
* Event ring setup: Allocate a normal ring, but also setup
24922492
* the event ring segment table (ERST). Section 4.9.3.
24932493
*/
2494+
val = 1 << HCS_ERST_MAX(xhci->hcs_params2);
2495+
val = min_t(unsigned int, ERST_MAX_SEGS, val);
24942496
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Allocating event ring");
2495-
xhci->event_ring = xhci_ring_alloc(xhci, ERST_NUM_SEGS, 1, TYPE_EVENT,
2496-
0, flags);
2497+
xhci->event_ring = xhci_ring_alloc(xhci, val, 1, TYPE_EVENT,
2498+
0, flags);
24972499
if (!xhci->event_ring)
24982500
goto fail;
24992501
if (xhci_check_trb_in_td_math(xhci) < 0)
@@ -2504,13 +2506,13 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
25042506
goto fail;
25052507

25062508
/* set ERST count with the number of entries in the segment table */
2507-
val = readl(&xhci->ir_set->erst_size);
2508-
val &= ERST_SIZE_MASK;
2509-
val |= ERST_NUM_SEGS;
2509+
val2 = readl(&xhci->ir_set->erst_size);
2510+
val2 &= ERST_SIZE_MASK;
2511+
val2 |= val;
25102512
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
25112513
"// Write ERST size = %i to ir_set 0 (some bits preserved)",
2512-
val);
2513-
writel(val, &xhci->ir_set->erst_size);
2514+
val2);
2515+
writel(val2, &xhci->ir_set->erst_size);
25142516

25152517
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
25162518
"// Set ERST entries to point to event ring.");

drivers/usb/host/xhci.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,8 +1643,8 @@ struct urb_priv {
16431643
* Each segment table entry is 4*32bits long. 1K seems like an ok size:
16441644
* (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
16451645
* meaning 64 ring segments.
1646-
* Initial allocated size of the ERST, in number of entries */
1647-
#define ERST_NUM_SEGS 1
1646+
* Maximum number of segments in the ERST */
1647+
#define ERST_MAX_SEGS 8
16481648
/* Initial allocated size of the ERST, in number of entries */
16491649
#define ERST_SIZE 64
16501650
/* Initial number of event segment rings allocated */

0 commit comments

Comments
 (0)