From patchwork Wed Mar 28 21:18:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 10314157 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0012160467 for ; Wed, 28 Mar 2018 21:19:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E4E5729188 for ; Wed, 28 Mar 2018 21:19:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D9CC32990A; Wed, 28 Mar 2018 21:19:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6FE6F29188 for ; Wed, 28 Mar 2018 21:19:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3683D6E240; Wed, 28 Mar 2018 21:19:48 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (mail.fireflyinternet.com [109.228.58.192]) by gabe.freedesktop.org (Postfix) with ESMTPS id E929B8982D for ; Wed, 28 Mar 2018 21:19:23 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 11193794-1500050 for multiple; Wed, 28 Mar 2018 22:19:18 +0100 Received: by haswell.alporthouse.com (sSMTP sendmail emulation); Wed, 28 Mar 2018 22:19:19 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Wed, 28 Mar 2018 22:18:51 +0100 Message-Id: <20180328211857.32457-10-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.16.3 In-Reply-To: <20180328211857.32457-1-chris@chris-wilson.co.uk> References: <20180328211857.32457-1-chris@chris-wilson.co.uk> MIME-Version: 1.0 X-Originating-IP: 78.156.65.138 X-Country: code=GB country="United Kingdom" ip=78.156.65.138 Subject: [Intel-gfx] [PATCH 09/15] drm/i915: Stop parking the signaler around reset X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP We cannot call kthread_park() from softirq context, so let's avoid it entirely during the reset. We wanted to suspend the signaler so that it would not mark a request as complete at the same time as we marked it as being in error. Instead of parking the signaling, stop the engine from advancing so that the GPU doesn't emit the breadcrumb for our choosen "guilty" request. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: MichaƂ Winiarski CC: Michel Thierry Cc: Jeff McGee Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_gem.c | 14 -------------- drivers/gpu/drm/i915/intel_lrc.c | 29 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 038867c96809..8a6acb1d5ad3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2928,18 +2928,6 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) */ intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL); - /* - * Prevent the signaler thread from updating the request - * state (by calling dma_fence_signal) as we are processing - * the reset. The write from the GPU of the seqno is - * asynchronous and the signaler thread may see a different - * value to us and declare the request complete, even though - * the reset routine have picked that request as the active - * (incomplete) request. This conflict is not handled - * gracefully! - */ - kthread_park(engine->breadcrumbs.signaler); - request = engine->reset.prepare(engine); if (request && request->fence.error == -EIO) request = ERR_PTR(-EIO); /* Previous reset failed! */ @@ -3136,8 +3124,6 @@ void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) { engine->reset.finish(engine); - kthread_unpark(engine->breadcrumbs.signaler); - intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index be1737d42d43..36f8490de178 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1732,6 +1732,29 @@ static void tasklet_kill_and_disable(struct tasklet_struct *t) smp_mb(); } +static void set_stop_engine(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + const u32 base = engine->mmio_base; + const i915_reg_t mode = RING_MI_MODE(base); + + I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING)); + if (__intel_wait_for_register_fw(dev_priv, + mode, MODE_IDLE, MODE_IDLE, + 1000, 0, + NULL)) + DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", + engine->name); +} + +static void clear_stop_engine(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + + I915_WRITE_FW(RING_MI_MODE(engine->mmio_base), + _MASKED_BIT_DISABLE(STOP_RING)); +} + static struct i915_request * execlists_reset_prepare(struct intel_engine_cs *engine) { @@ -1768,6 +1791,9 @@ execlists_reset_prepare(struct intel_engine_cs *engine) if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) process_csb(engine); + intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL); + set_stop_engine(engine); + /* * The last active request can then be no later than the last request * now in ELSP[0]. So search backwards from there, so that if the GPU @@ -1869,6 +1895,9 @@ static void execlists_reset(struct intel_engine_cs *engine, static void execlists_reset_finish(struct intel_engine_cs *engine) { + clear_stop_engine(engine); + intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL); + tasklet_enable(&engine->execlists.tasklet); GEM_TRACE("%s\n", engine->name); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 5dadbc435c0e..03b84cd45314 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -530,8 +530,35 @@ static int init_ring_common(struct intel_engine_cs *engine) return ret; } +static void set_stop_engine(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + const u32 base = engine->mmio_base; + const i915_reg_t mode = RING_MI_MODE(base); + + I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING)); + if (__intel_wait_for_register_fw(dev_priv, + mode, MODE_IDLE, MODE_IDLE, + 1000, 0, + NULL)) + DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", + engine->name); +} + +static void clear_stop_engine(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + + I915_WRITE_FW(RING_MI_MODE(engine->mmio_base), + _MASKED_BIT_DISABLE(STOP_RING)); +} + static struct i915_request *reset_prepare(struct intel_engine_cs *engine) { + intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL); + if (INTEL_GEN(engine->i915) >= 3) + set_stop_engine(engine); + if (engine->irq_seqno_barrier) engine->irq_seqno_barrier(engine); @@ -608,6 +635,9 @@ static void reset_ring(struct intel_engine_cs *engine, static void reset_finish(struct intel_engine_cs *engine) { + if (INTEL_GEN(engine->i915) >= 3) + clear_stop_engine(engine); + intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL); } static int intel_rcs_ctx_init(struct i915_request *rq)