Commit 633cf8f5 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter

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: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent a2165e31
...@@ -141,7 +141,7 @@ void i915_kernel_lost_context(struct drm_device * dev) ...@@ -141,7 +141,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; ring->head = I915_READ_HEAD(ring) & HEAD_ADDR;
ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
ring->space = ring->head - (ring->tail + 8); ring->space = ring->head - (ring->tail + I915_RING_FREE_SPACE);
if (ring->space < 0) if (ring->space < 0)
ring->space += ring->size; ring->space += ring->size;
......
...@@ -45,7 +45,7 @@ struct pipe_control { ...@@ -45,7 +45,7 @@ struct pipe_control {
static inline int ring_space(struct intel_ring_buffer *ring) static inline int ring_space(struct intel_ring_buffer *ring)
{ {
int space = (ring->head & HEAD_ADDR) - (ring->tail + 8); int space = (ring->head & HEAD_ADDR) - (ring->tail + I915_RING_FREE_SPACE);
if (space < 0) if (space < 0)
space += ring->size; space += ring->size;
return space; return space;
...@@ -1227,7 +1227,7 @@ static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n) ...@@ -1227,7 +1227,7 @@ static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n)
if (request->tail == -1) if (request->tail == -1)
continue; continue;
space = request->tail - (ring->tail + 8); space = request->tail - (ring->tail + I915_RING_FREE_SPACE);
if (space < 0) if (space < 0)
space += ring->size; space += ring->size;
if (space >= n) { if (space >= n) {
......
#ifndef _INTEL_RINGBUFFER_H_ #ifndef _INTEL_RINGBUFFER_H_
#define _INTEL_RINGBUFFER_H_ #define _INTEL_RINGBUFFER_H_
/*
* 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"
*
* "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."
*/
#define I915_RING_FREE_SPACE 64
struct intel_hw_status_page { struct intel_hw_status_page {
u32 *page_addr; u32 *page_addr;
unsigned int gfx_addr; unsigned int gfx_addr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment