From patchwork Fri Jun 17 07:09:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: arun.siluvery@linux.intel.com X-Patchwork-Id: 9182703 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 564A26075F for ; Fri, 17 Jun 2016 07:09:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 44BFA283A1 for ; Fri, 17 Jun 2016 07:09:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 39D8D2839E; Fri, 17 Jun 2016 07:09:58 +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]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CCBFF283A1 for ; Fri, 17 Jun 2016 07:09:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F29B76EAE6; Fri, 17 Jun 2016 07:09:48 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 7EB146EADD for ; Fri, 17 Jun 2016 07:09:30 +0000 (UTC) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga102.jf.intel.com with ESMTP; 17 Jun 2016 00:09:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.26,482,1459839600"; d="scan'208"; a="1003894757" Received: from asiluver-linux.isw.intel.com ([10.102.226.117]) by fmsmga002.fm.intel.com with ESMTP; 17 Jun 2016 00:09:29 -0700 From: Arun Siluvery To: intel-gfx@lists.freedesktop.org Date: Fri, 17 Jun 2016 08:09:06 +0100 Message-Id: <1466147355-4635-7-git-send-email-arun.siluvery@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1466147355-4635-1-git-send-email-arun.siluvery@linux.intel.com> References: <1466147355-4635-1-git-send-email-arun.siluvery@linux.intel.com> Cc: Tomas Elf Subject: [Intel-gfx] [PATCH v2 06/15] drm/i915/tdr: Capture engine state before reset X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Minimal state of engine is saved before resetting it, this state includes head, current active request. A consistency check is performed on the active request to make sure that the context HW is executing is same as the one for the active request. This check is important because engine recovery in execlist mode relies on the context resubmission after reset. If the state is inconsistent, resubmission can cause unforseen side-effects such as unexpected preemptions. Engine is restarted after reset with this state. Signed-off-by: Tomas Elf Signed-off-by: Arun Siluvery --- drivers/gpu/drm/i915/intel_lrc.c | 80 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.h | 3 ++ drivers/gpu/drm/i915/intel_ringbuffer.h | 10 +++++ 3 files changed, 93 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 35255ce..b83552a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1022,6 +1022,82 @@ void intel_lr_context_unpin(struct i915_gem_context *ctx, i915_gem_context_unreference(ctx); } +/** + * intel_execlist_get_current_request() - returns request currently processed + * by the given engine + * + * @engine: Engine currently running context to be returned. + * + * Returns: + * req - if a valid req is found in the execlist queue and HW also agrees. + * caller has to dereference at the end of its lifecycle. + * NULL - otherwise + */ +static struct drm_i915_gem_request * +intel_execlist_get_current_request(struct intel_engine_cs *engine) +{ + struct drm_i915_gem_request *req; + unsigned long flags; + + spin_lock_irqsave(&engine->execlist_lock, flags); + + req = list_first_entry_or_null(&engine->execlist_queue, + struct drm_i915_gem_request, + execlist_link); + /* + * Only acknowledge the request in the execlist queue if it's actually + * been submitted to hardware, otherwise there's the risk of + * inconsistency between the (unsubmitted) request and the idle + * hardware state. + */ + if (req && req->ctx && req->elsp_submitted) { + u32 execlist_status; + u32 hw_context; + u32 hw_active; + struct drm_i915_private *dev_priv = engine->i915; + + hw_context = I915_READ(RING_EXECLIST_STATUS_CTX_ID(engine)); + execlist_status = I915_READ(RING_EXECLIST_STATUS_LO(engine)); + hw_active = ((execlist_status & EXECLIST_STATUS_ELEMENT0_ACTIVE) || + (execlist_status & EXECLIST_STATUS_ELEMENT1_ACTIVE)); + + /* If both HW and driver agrees then we found it */ + if (hw_active && hw_context == req->ctx->hw_id) + i915_gem_request_reference(req); + } else { + req = NULL; + WARN(1, "No active request for %s\n", engine->name); + } + + spin_unlock_irqrestore(&engine->execlist_lock, flags); + + return req; +} + +/** + * gen8_engine_state_save() - save minimum engine state + * @engine: engine whose state is to be saved + * @state: location where the state is saved + * + * captured engine state includes head, tail, active request. After reset, + * engine is restarted with this state. + * + * Returns: + * 0 if ok, otherwise propagates error codes. + */ +static int gen8_engine_state_save(struct intel_engine_cs *engine, + struct intel_engine_cs_state *state) +{ + struct drm_i915_private *dev_priv = engine->i915; + + state->head = I915_READ_HEAD(engine); + state->req = intel_execlist_get_current_request(engine); + if (!state->req) + return -EINVAL; + + return 0; +} + static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req) { int ret, i; @@ -1977,6 +2053,10 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine) engine->emit_bb_start = gen8_emit_bb_start; engine->get_seqno = gen8_get_seqno; engine->set_seqno = gen8_set_seqno; + + /* engine reset supporting functions */ + engine->save = gen8_engine_state_save; + if (IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1)) { engine->irq_seqno_barrier = bxt_a_seqno_barrier; engine->set_seqno = bxt_a_set_seqno; diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index a8db42a..0ef6fb5 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -31,7 +31,10 @@ /* Execlists regs */ #define RING_ELSP(ring) _MMIO((ring)->mmio_base + 0x230) #define RING_EXECLIST_STATUS_LO(ring) _MMIO((ring)->mmio_base + 0x234) +#define EXECLIST_STATUS_ELEMENT0_ACTIVE (1 << 14) +#define EXECLIST_STATUS_ELEMENT1_ACTIVE (1 << 15) #define RING_EXECLIST_STATUS_HI(ring) _MMIO((ring)->mmio_base + 0x234 + 4) +#define RING_EXECLIST_STATUS_CTX_ID(ring) RING_EXECLIST_STATUS_HI(ring) #define RING_CONTEXT_CONTROL(ring) _MMIO((ring)->mmio_base + 0x244) #define CTX_CTRL_INHIBIT_SYN_CTX_SWITCH (1 << 3) #define CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT (1 << 0) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index b33c876..daf2727 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -141,6 +141,12 @@ struct i915_ctx_workarounds { struct drm_i915_gem_object *obj; }; +struct intel_engine_cs_state { + u32 head; + u32 tail; + struct drm_i915_gem_request *req; +}; + struct intel_engine_cs { struct drm_i915_private *i915; const char *name; @@ -204,6 +210,10 @@ struct intel_engine_cs { #define I915_DISPATCH_RS 0x4 void (*cleanup)(struct intel_engine_cs *ring); + /* engine reset supporting functions */ + int (*save)(struct intel_engine_cs *engine, + struct intel_engine_cs_state *state); + /* GEN8 signal/wait table - never trust comments! * signal to signal to signal to signal to signal to * RCS VCS BCS VECS VCS2