From 29dcb570264ce1d887ba8ac729ec2103abf1802e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 Apr 2016 07:29:13 +0100 Subject: [PATCH] drm/i915: Move the hw semaphore initialisation from GEM to the engine Since we are setting engine local values that are tied to the hardware, move it out of i915_gem_init_seqno() into the intel_ring_init_seqno() backend, next to where the other hw semaphore registers are written. v2: Make the explanatory comment about always resetting the semaphores to 0 irrespective of the value of the reset seqno. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Joonas Lahtinen Reviewed-by: Mika Kuoppala Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1460010558-10705-4-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 8 ++------ drivers/gpu/drm/i915/intel_ringbuffer.c | 11 +++++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3e9e6f9b66f5..65f18f583ae1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2468,7 +2468,7 @@ i915_gem_init_seqno(struct drm_device *dev, u32 seqno) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; - int ret, j; + int ret; /* Carefully retire all requests without writing to the rings */ for_each_engine(engine, dev_priv) { @@ -2479,13 +2479,9 @@ i915_gem_init_seqno(struct drm_device *dev, u32 seqno) i915_gem_retire_requests(dev); /* Finally reset hw state */ - for_each_engine(engine, dev_priv) { + for_each_engine(engine, dev_priv) intel_ring_init_seqno(engine, seqno); - for (j = 0; j < ARRAY_SIZE(engine->semaphore.sync_seqno); j++) - engine->semaphore.sync_seqno[j] = 0; - } - return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 371f4c1fc33c..69852ac4018d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2552,14 +2552,25 @@ void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno) { struct drm_i915_private *dev_priv = to_i915(engine->dev); + /* Our semaphore implementation is strictly monotonic (i.e. we proceed + * so long as the semaphore value in the register/page is greater + * than the sync value), so whenever we reset the seqno, + * so long as we reset the tracking semaphore value to 0, it will + * always be before the next request's seqno. If we don't reset + * the semaphore value, then when the seqno moves backwards all + * future waits will complete instantly (causing rendering corruption). + */ if (INTEL_INFO(dev_priv)->gen == 6 || INTEL_INFO(dev_priv)->gen == 7) { I915_WRITE(RING_SYNC_0(engine->mmio_base), 0); I915_WRITE(RING_SYNC_1(engine->mmio_base), 0); if (HAS_VEBOX(dev_priv)) I915_WRITE(RING_SYNC_2(engine->mmio_base), 0); } + memset(engine->semaphore.sync_seqno, 0, + sizeof(engine->semaphore.sync_seqno)); engine->set_seqno(engine, seqno); + engine->hangcheck.seqno = seqno; }