From cbf4b77af11ba93ea2ed7effa37da2a39e970851 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 9 Mar 2017 13:20:04 +0000 Subject: drm/i915/guc: Fix request re-submission after reset In order to ensure no missed interrupts we must first re-direct the interrupts to GuC, and only then re-submit the requests to be replayed after a GPU reset. Otherwise context switch can fire before GuC has been set up to receive it triggering more hangs. v2: Rebase. Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Cc: Michal Wajdeczko Cc: Mika Kuoppala Cc: Oscar Mateo Cc: Sagar Arun Kamble Cc: Arkadiusz Hiler Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/20170309132005.1317-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_guc_submission.c | 32 ++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_guc_submission.c') diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index beb38e30d0e9..41f2dd87b413 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -936,6 +936,26 @@ static void guc_reset_wq(struct i915_guc_client *client) client->wq_tail = 0; } +static void guc_interrupts_capture(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + int irqs; + + /* tell all command streamers to forward interrupts (but not vblank) to GuC */ + irqs = _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); + for_each_engine(engine, dev_priv, id) + I915_WRITE(RING_MODE_GEN7(engine), irqs); + + /* route USER_INTERRUPT to Host, all others are sent to GuC. */ + irqs = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT | + GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; + /* These three registers have the same bit definitions */ + I915_WRITE(GUC_BCS_RCS_IER, ~irqs); + I915_WRITE(GUC_VCS2_VCS1_IER, ~irqs); + I915_WRITE(GUC_WD_VECS_IER, ~irqs); +} + int i915_guc_submission_enable(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; @@ -953,13 +973,17 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) /* Take over from manual control of ELSP (execlists) */ for_each_engine(engine, dev_priv, id) { - const int wqi_size = sizeof(struct guc_wq_item); - struct drm_i915_gem_request *rq; - engine->submit_request = i915_guc_submit; engine->schedule = NULL; + } + + guc_interrupts_capture(dev_priv); + + /* Replay the current set of previously submitted requests */ + for_each_engine(engine, dev_priv, id) { + const int wqi_size = sizeof(struct guc_wq_item); + struct drm_i915_gem_request *rq; - /* Replay the current set of previously submitted requests */ spin_lock_irq(&engine->timeline->lock); list_for_each_entry(rq, &engine->timeline->requests, link) { guc_client_update_wq_rsvd(client, wqi_size); -- cgit v1.2.3-55-g7522