Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Don't allow ring tail to reach the same cacheline as head

From BSpec:
"If the Ring Buffer Head Pointer and the Tail Pointer are on the same
cacheline, the Head Pointer must not be greater than the Tail
Pointer."

The easiest way to enforce this is to reduce the reported ring space.

References:
Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use"
Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use"
Gen4+ BSpec "vol1c Memory Interface and Command Stream" / 5.3.4.5 "Ring Buffer Use"

v2: Include the exact BSpec references in the description

v3: s/64/I915_RING_FREE_SPACE, and add the BSpec information to the code

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

authored by

Ville Syrjälä and committed by
Daniel Vetter
633cf8f5 a2165e31

+14 -3
+1 -1
drivers/gpu/drm/i915/i915_dma.c
··· 141 141 142 142 ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; 143 143 ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; 144 - ring->space = ring->head - (ring->tail + 8); 144 + ring->space = ring->head - (ring->tail + I915_RING_FREE_SPACE); 145 145 if (ring->space < 0) 146 146 ring->space += ring->size; 147 147
+2 -2
drivers/gpu/drm/i915/intel_ringbuffer.c
··· 45 45 46 46 static inline int ring_space(struct intel_ring_buffer *ring) 47 47 { 48 - int space = (ring->head & HEAD_ADDR) - (ring->tail + 8); 48 + int space = (ring->head & HEAD_ADDR) - (ring->tail + I915_RING_FREE_SPACE); 49 49 if (space < 0) 50 50 space += ring->size; 51 51 return space; ··· 1227 1227 if (request->tail == -1) 1228 1228 continue; 1229 1229 1230 - space = request->tail - (ring->tail + 8); 1230 + space = request->tail - (ring->tail + I915_RING_FREE_SPACE); 1231 1231 if (space < 0) 1232 1232 space += ring->size; 1233 1233 if (space >= n) {
+11
drivers/gpu/drm/i915/intel_ringbuffer.h
··· 1 1 #ifndef _INTEL_RINGBUFFER_H_ 2 2 #define _INTEL_RINGBUFFER_H_ 3 3 4 + /* 5 + * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use" 6 + * Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use" 7 + * Gen4+ BSpec "vol1c Memory Interface and Command Stream" / 5.3.4.5 "Ring Buffer Use" 8 + * 9 + * "If the Ring Buffer Head Pointer and the Tail Pointer are on the same 10 + * cacheline, the Head Pointer must not be greater than the Tail 11 + * Pointer." 12 + */ 13 + #define I915_RING_FREE_SPACE 64 14 + 4 15 struct intel_hw_status_page { 5 16 u32 *page_addr; 6 17 unsigned int gfx_addr;