|
Takashi Iwai |
e71951 |
From 6acbea89efbdc6aef56bc6f364d4d8b72a5fc145 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
e71951 |
From: Michel Thierry <michel.thierry@intel.com>
|
|
Takashi Iwai |
e71951 |
Date: Tue, 31 Oct 2017 15:53:09 -0700
|
|
Takashi Iwai |
e71951 |
Subject: [PATCH] drm/i915/guc: Add support for reset engine using GuC commands
|
|
Takashi Iwai |
e71951 |
Git-commit: 6acbea89efbdc6aef56bc6f364d4d8b72a5fc145
|
|
Takashi Iwai |
e71951 |
Patch-mainline: v4.16-rc1
|
|
Takashi Iwai |
e71951 |
References: FATE#322643 bsc#1055900
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
This patch adds per engine reset and recovery (TDR) support when GuC is
|
|
Takashi Iwai |
e71951 |
used to submit workloads to GPU.
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
In the case of i915 directly submission to ELSP, driver manages hang
|
|
Takashi Iwai |
e71951 |
detection, recovery and resubmission. With GuC submission these tasks
|
|
Takashi Iwai |
e71951 |
are shared between driver and GuC. i915 is still responsible for detecting
|
|
Takashi Iwai |
e71951 |
a hang, and when it does it only requests GuC to reset that Engine. GuC
|
|
Takashi Iwai |
e71951 |
internally manages acquiring forcewake and idling the engine before
|
|
Takashi Iwai |
e71951 |
resetting it.
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
Once the reset is successful, i915 takes over again and handles the
|
|
Takashi Iwai |
e71951 |
resubmission. The scheduler in i915 knows which requests are pending so
|
|
Takashi Iwai |
e71951 |
after resetting a engine, pending workloads/requests are resubmitted
|
|
Takashi Iwai |
e71951 |
again.
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
V2: s/i915_guc_request_engine_reset/i915_guc_reset_engine/ to match the
|
|
Takashi Iwai |
e71951 |
non-guc function names.
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
V3: Removed debug message about engine restarting from which request,
|
|
Takashi Iwai |
e71951 |
since the new baseline do it regardless of submission mode. (Chris)
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
V4: Rebase.
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
V5: Do not pass unnecessary reporting flags to the fw (Jeff);
|
|
Takashi Iwai |
e71951 |
tasklet_schedule(&execlists->irq_tasklet) handles the resubmit; rebase.
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
V6: Rename the existing reset engine function and share a similar
|
|
Takashi Iwai |
e71951 |
interface between guc and non-guc paths (Chris).
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
Signed-off-by: Michel Thierry <michel.thierry@intel.com>
|
|
Takashi Iwai |
e71951 |
Cc: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Takashi Iwai |
e71951 |
Link: https://patchwork.freedesktop.org/patch/msgid/20171031225309.10888-1-michel.thierry@intel.com
|
|
Takashi Iwai |
e71951 |
Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
|
|
Takashi Iwai |
e71951 |
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Takashi Iwai |
e71951 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
---
|
|
Takashi Iwai |
e71951 |
drivers/gpu/drm/i915/i915_drv.c | 14 ++++++++++++--
|
|
Takashi Iwai |
e71951 |
drivers/gpu/drm/i915/i915_drv.h | 2 ++
|
|
Takashi Iwai |
e71951 |
drivers/gpu/drm/i915/intel_guc.c | 24 ++++++++++++++++++++++++
|
|
Takashi Iwai |
e71951 |
drivers/gpu/drm/i915/intel_guc_fwif.h | 1 +
|
|
Takashi Iwai |
e71951 |
drivers/gpu/drm/i915/intel_uncore.c | 5 -----
|
|
Takashi Iwai |
e71951 |
5 files changed, 39 insertions(+), 7 deletions(-)
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
--- a/drivers/gpu/drm/i915/i915_drv.c
|
|
Takashi Iwai |
e71951 |
+++ b/drivers/gpu/drm/i915/i915_drv.c
|
|
Takashi Iwai |
e71951 |
@@ -1950,6 +1950,12 @@ error:
|
|
Takashi Iwai |
e71951 |
goto finish;
|
|
Takashi Iwai |
e71951 |
}
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
+static inline int intel_gt_reset_engine(struct drm_i915_private *dev_priv,
|
|
Takashi Iwai |
e71951 |
+ struct intel_engine_cs *engine)
|
|
Takashi Iwai |
e71951 |
+{
|
|
Takashi Iwai |
e71951 |
+ return intel_gpu_reset(dev_priv, intel_engine_flag(engine));
|
|
Takashi Iwai |
e71951 |
+}
|
|
Takashi Iwai |
e71951 |
+
|
|
Takashi Iwai |
e71951 |
/**
|
|
Takashi Iwai |
e71951 |
* i915_reset_engine - reset GPU engine to recover from a hang
|
|
Takashi Iwai |
e71951 |
* @engine: engine to reset
|
|
Takashi Iwai |
e71951 |
@@ -1984,10 +1990,14 @@ int i915_reset_engine(struct intel_engin
|
|
Takashi Iwai |
e71951 |
goto out;
|
|
Takashi Iwai |
e71951 |
}
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
- ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine));
|
|
Takashi Iwai |
e71951 |
+ if (!engine->i915->guc.execbuf_client)
|
|
Takashi Iwai |
e71951 |
+ ret = intel_gt_reset_engine(engine->i915, engine);
|
|
Takashi Iwai |
e71951 |
+ else
|
|
Takashi Iwai |
e71951 |
+ ret = intel_guc_reset_engine(&engine->i915->guc, engine);
|
|
Takashi Iwai |
e71951 |
if (ret) {
|
|
Takashi Iwai |
e71951 |
/* If we fail here, we expect to fallback to a global reset */
|
|
Takashi Iwai |
e71951 |
- DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n",
|
|
Takashi Iwai |
e71951 |
+ DRM_DEBUG_DRIVER("%sFailed to reset %s, ret=%d\n",
|
|
Takashi Iwai |
e71951 |
+ engine->i915->guc.execbuf_client ? "GuC " : "",
|
|
Takashi Iwai |
e71951 |
engine->name, ret);
|
|
Takashi Iwai |
e71951 |
goto out;
|
|
Takashi Iwai |
e71951 |
}
|
|
Takashi Iwai |
e71951 |
--- a/drivers/gpu/drm/i915/i915_drv.h
|
|
Takashi Iwai |
e71951 |
+++ b/drivers/gpu/drm/i915/i915_drv.h
|
|
Takashi Iwai |
e71951 |
@@ -3282,6 +3282,8 @@ extern int i915_reset_engine(struct inte
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
extern bool intel_has_reset_engine(struct drm_i915_private *dev_priv);
|
|
Takashi Iwai |
e71951 |
extern int intel_reset_guc(struct drm_i915_private *dev_priv);
|
|
Takashi Iwai |
e71951 |
+extern int intel_guc_reset_engine(struct intel_guc *guc,
|
|
Takashi Iwai |
e71951 |
+ struct intel_engine_cs *engine);
|
|
Takashi Iwai |
e71951 |
extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine);
|
|
Takashi Iwai |
e71951 |
extern void intel_hangcheck_init(struct drm_i915_private *dev_priv);
|
|
Takashi Iwai |
e71951 |
extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
|
|
Takashi Iwai |
e71951 |
--- a/drivers/gpu/drm/i915/intel_guc.c
|
|
Takashi Iwai |
e71951 |
+++ b/drivers/gpu/drm/i915/intel_guc.c
|
|
Takashi Iwai |
e71951 |
@@ -24,6 +24,7 @@
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
#include "intel_guc.h"
|
|
Takashi Iwai |
e71951 |
#include "i915_drv.h"
|
|
Takashi Iwai |
e71951 |
+#include "i915_guc_submission.h"
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
static void gen8_guc_raise_irq(struct intel_guc *guc)
|
|
Takashi Iwai |
e71951 |
{
|
|
Takashi Iwai |
e71951 |
@@ -282,6 +283,29 @@ int intel_guc_suspend(struct drm_i915_pr
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
return intel_guc_send(guc, data, ARRAY_SIZE(data));
|
|
Takashi Iwai |
e71951 |
}
|
|
Takashi Iwai |
e71951 |
+
|
|
Takashi Iwai |
e71951 |
+/**
|
|
Takashi Iwai |
e71951 |
+ * intel_guc_reset_engine() - ask GuC to reset an engine
|
|
Takashi Iwai |
e71951 |
+ * @guc: intel_guc structure
|
|
Takashi Iwai |
e71951 |
+ * @engine: engine to be reset
|
|
Takashi Iwai |
e71951 |
+ */
|
|
Takashi Iwai |
e71951 |
+int intel_guc_reset_engine(struct intel_guc *guc,
|
|
Takashi Iwai |
e71951 |
+ struct intel_engine_cs *engine)
|
|
Takashi Iwai |
e71951 |
+{
|
|
Takashi Iwai |
e71951 |
+ u32 data[7];
|
|
Takashi Iwai |
e71951 |
+
|
|
Takashi Iwai |
e71951 |
+ GEM_BUG_ON(!guc->execbuf_client);
|
|
Takashi Iwai |
e71951 |
+
|
|
Takashi Iwai |
e71951 |
+ data[0] = INTEL_GUC_ACTION_REQUEST_ENGINE_RESET;
|
|
Takashi Iwai |
e71951 |
+ data[1] = engine->guc_id;
|
|
Takashi Iwai |
e71951 |
+ data[2] = 0;
|
|
Takashi Iwai |
e71951 |
+ data[3] = 0;
|
|
Takashi Iwai |
e71951 |
+ data[4] = 0;
|
|
Takashi Iwai |
e71951 |
+ data[5] = guc->execbuf_client->stage_id;
|
|
Takashi Iwai |
e71951 |
+ data[6] = guc_ggtt_offset(guc->shared_data);
|
|
Takashi Iwai |
e71951 |
+
|
|
Takashi Iwai |
e71951 |
+ return intel_guc_send(guc, data, ARRAY_SIZE(data));
|
|
Takashi Iwai |
e71951 |
+}
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
/**
|
|
Takashi Iwai |
e71951 |
* intel_guc_resume() - notify GuC resuming from suspend state
|
|
Takashi Iwai |
e71951 |
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
|
|
Takashi Iwai |
e71951 |
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
|
|
Takashi Iwai |
e71951 |
@@ -574,6 +574,7 @@ struct guc_shared_ctx_data {
|
|
Takashi Iwai |
e71951 |
enum intel_guc_action {
|
|
Takashi Iwai |
e71951 |
INTEL_GUC_ACTION_DEFAULT = 0x0,
|
|
Takashi Iwai |
e71951 |
INTEL_GUC_ACTION_REQUEST_PREEMPTION = 0x2,
|
|
Takashi Iwai |
e71951 |
+ INTEL_GUC_ACTION_REQUEST_ENGINE_RESET = 0x3,
|
|
Takashi Iwai |
e71951 |
INTEL_GUC_ACTION_SAMPLE_FORCEWAKE = 0x6,
|
|
Takashi Iwai |
e71951 |
INTEL_GUC_ACTION_ALLOCATE_DOORBELL = 0x10,
|
|
Takashi Iwai |
e71951 |
INTEL_GUC_ACTION_DEALLOCATE_DOORBELL = 0x20,
|
|
Takashi Iwai |
e71951 |
--- a/drivers/gpu/drm/i915/intel_uncore.c
|
|
Takashi Iwai |
e71951 |
+++ b/drivers/gpu/drm/i915/intel_uncore.c
|
|
Takashi Iwai |
e71951 |
@@ -1805,14 +1805,9 @@ bool intel_has_gpu_reset(struct drm_i915
|
|
Takashi Iwai |
e71951 |
return intel_get_gpu_reset(dev_priv) != NULL;
|
|
Takashi Iwai |
e71951 |
}
|
|
Takashi Iwai |
e71951 |
|
|
Takashi Iwai |
e71951 |
-/*
|
|
Takashi Iwai |
e71951 |
- * When GuC submission is enabled, GuC manages ELSP and can initiate the
|
|
Takashi Iwai |
e71951 |
- * engine reset too. For now, fall back to full GPU reset if it is enabled.
|
|
Takashi Iwai |
e71951 |
- */
|
|
Takashi Iwai |
e71951 |
bool intel_has_reset_engine(struct drm_i915_private *dev_priv)
|
|
Takashi Iwai |
e71951 |
{
|
|
Takashi Iwai |
e71951 |
return (dev_priv->info.has_reset_engine &&
|
|
Takashi Iwai |
e71951 |
- !dev_priv->guc.execbuf_client &&
|
|
Takashi Iwai |
e71951 |
i915_modparams.reset >= 2);
|
|
Takashi Iwai |
e71951 |
}
|
|
Takashi Iwai |
e71951 |
|