From b72f3acb71646de073abdc070fe1108866c96634 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 4 Jan 2011 17:34:02 +0000 Subject: [PATCH] drm/i915: Handle ringbuffer stalls when flushing Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 4 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 12 +-- drivers/gpu/drm/i915/intel_ringbuffer.c | 86 +++++++++++++--------- drivers/gpu/drm/i915/intel_ringbuffer.h | 6 +- 4 files changed, 65 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f9c093c08d58..07b62449b9e1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2148,8 +2148,8 @@ i915_gem_flush_ring(struct drm_device *dev, uint32_t invalidate_domains, uint32_t flush_domains) { - ring->flush(ring, invalidate_domains, flush_domains); - i915_gem_process_flushing_list(dev, flush_domains, ring); + if (ring->flush(ring, invalidate_domains, flush_domains) == 0) + i915_gem_process_flushing_list(dev, flush_domains, ring); } static int i915_ring_idle(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 0d42de42868c..1b78b66dd77e 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -924,7 +924,7 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) { struct drm_i915_gem_request *request; - u32 flush_domains; + u32 invalidate; /* * Ensure that the commands in the batch buffer are @@ -932,11 +932,13 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev, * * The sampler always gets flushed on i965 (sigh). */ - flush_domains = 0; + invalidate = I915_GEM_DOMAIN_COMMAND; if (INTEL_INFO(dev)->gen >= 4) - flush_domains |= I915_GEM_DOMAIN_SAMPLER; - - ring->flush(ring, I915_GEM_DOMAIN_COMMAND, flush_domains); + invalidate |= I915_GEM_DOMAIN_SAMPLER; + if (ring->flush(ring, invalidate, 0)) { + i915_gem_next_request_seqno(dev, ring); + return; + } /* Add a breadcrumb for the completion of the batch buffer */ request = kzalloc(sizeof(*request), GFP_KERNEL); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2de0e45464c5..aa8f6abf16f2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -48,7 +48,7 @@ static u32 i915_gem_get_seqno(struct drm_device *dev) return seqno; } -static void +static int render_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) @@ -56,6 +56,7 @@ render_ring_flush(struct intel_ring_buffer *ring, struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; u32 cmd; + int ret; #if WATCH_EXEC DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, @@ -116,12 +117,16 @@ render_ring_flush(struct intel_ring_buffer *ring, #if WATCH_EXEC DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); #endif - if (intel_ring_begin(ring, 2) == 0) { - intel_ring_emit(ring, cmd); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - } + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; + + intel_ring_emit(ring, cmd); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); } + + return 0; } static void ring_write_tail(struct intel_ring_buffer *ring, @@ -534,19 +539,24 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) POSTING_READ(mmio); } -static void +static int bsd_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { + int ret; + if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) - return; + return 0; - if (intel_ring_begin(ring, 2) == 0) { - intel_ring_emit(ring, MI_FLUSH); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - } + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; + + intel_ring_emit(ring, MI_FLUSH); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + return 0; } static int @@ -980,20 +990,25 @@ static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); } -static void gen6_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) +static int gen6_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) { + int ret; + if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) - return; + return 0; - if (intel_ring_begin(ring, 4) == 0) { - intel_ring_emit(ring, MI_FLUSH_DW); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); - } + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; + + intel_ring_emit(ring, MI_FLUSH_DW); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); + return 0; } static int @@ -1122,20 +1137,25 @@ static int blt_ring_begin(struct intel_ring_buffer *ring, return intel_ring_begin(ring, 4); } -static void blt_ring_flush(struct intel_ring_buffer *ring, +static int blt_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { + int ret; + if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) - return; + return 0; - if (blt_ring_begin(ring, 4) == 0) { - intel_ring_emit(ring, MI_FLUSH_DW); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); - } + ret = blt_ring_begin(ring, 4); + if (ret) + return ret; + + intel_ring_emit(ring, MI_FLUSH_DW); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); + return 0; } static void blt_ring_cleanup(struct intel_ring_buffer *ring) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index bbbf505c8b56..5969c2ed1028 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -63,9 +63,9 @@ struct intel_ring_buffer { void (*write_tail)(struct intel_ring_buffer *ring, u32 value); - void (*flush)(struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains); + int __must_check (*flush)(struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains); int (*add_request)(struct intel_ring_buffer *ring, u32 *seqno); u32 (*get_seqno)(struct intel_ring_buffer *ring); -- 2.20.1