drm/i915: Don't allow ring tail to reach the same cacheline as head
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 3 Dec 2012 16:43:32 +0000 (18:43 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 3 Dec 2012 17:31:20 +0000 (18:31 +0100)
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>
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index 80ed75117b6dbbf386ad7d5a2ea566f148c90e8c..8f63cd5de4b445cd247dddf078af7dc8686d49a5 100644 (file)
@@ -141,7 +141,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
 
        ring->head = I915_READ_HEAD(ring) & HEAD_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)
                ring->space += ring->size;
 
index bc7cf7c6310870a91e73758975689e5190d0de6b..2346b920bd86ef96c70d7632ba13c254b21302a4 100644 (file)
@@ -45,7 +45,7 @@ struct pipe_control {
 
 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)
                space += ring->size;
        return space;
@@ -1227,7 +1227,7 @@ static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n)
                if (request->tail == -1)
                        continue;
 
-               space = request->tail - (ring->tail + 8);
+               space = request->tail - (ring->tail + I915_RING_FREE_SPACE);
                if (space < 0)
                        space += ring->size;
                if (space >= n) {
index d4b7416fa1b014b722e479e8d63d0f381448dba7..526182ed0c6d78b83bf35265f2d98987fab1652a 100644 (file)
@@ -1,6 +1,17 @@
 #ifndef _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 {
        u32             *page_addr;
        unsigned int    gfx_addr;