From d2d1f99d2a6a55380438043b7bcf7b443bdcb775 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 1 Feb 2012 23:32:19 +0000 Subject: [PATCH] drm/i915: Prefer the ring->last_retired_head whilst we having pending requests Closes a race with reading ACTHD directly with requests outstanding. This is the less fugly version. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 25 ++++++++++++++++++------- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b26e951..96c6f66 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1237,6 +1237,8 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) } void i915_gem_retire_requests(struct drm_device *dev); +void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring); + void i915_gem_reset(struct drm_device *dev); void i915_gem_clflush_object(struct drm_i915_gem_object *obj); int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 900a93c..d2e0fac 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1935,7 +1935,7 @@ void i915_gem_reset(struct drm_device *dev) /** * This function clears the request list as sequence numbers are passed. */ -static void +void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) { uint32_t seqno; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 255245b..f4f643e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1058,8 +1058,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long end; - i915_gem_retire_requests(dev); - if (ring->last_retired_head) { ring->head = ring->last_retired_head; ring->last_retired_head = 0; @@ -1081,11 +1079,24 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) end = jiffies + 3 * HZ; do { - ring->head = I915_READ_HEAD(ring); - ring->space = ring_space(ring); - if (ring->space >= n) { - trace_i915_ring_wait_end(ring); - return 0; + if (!list_empty(&ring->request_list)) { + i915_gem_retire_requests_ring(ring); + + if (ring->last_retired_head) { + ring->head = ring->last_retired_head; + ring->last_retired_head = 0; + + ring->space = ring_space(ring); + if (ring->space >= n) + return 0; + } + } else { + ring->head = I915_READ_HEAD(ring); + ring->space = ring_space(ring); + if (ring->space >= n) { + trace_i915_ring_wait_end(ring); + return 0; + } } if (dev->primary->master) { -- 1.7.8.3