[PATCH 5/5] reset-only

Chris Wilson chris at chris-wilson.co.uk
Sat Jun 22 09:19:22 UTC 2019


---
 drivers/gpu/drm/i915/gt/intel_reset.c    | 48 ++++++++++++++++--------
 drivers/gpu/drm/i915/gt/selftest_reset.c |  8 +++-
 2 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index 25ce2f26b96e..45f30153a6e1 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -669,8 +669,10 @@ int intel_reset_guc(struct drm_i915_private *i915)
  * Ensure irq handler finishes, and not run again.
  * Also return the active request so that we only search for it once.
  */
-static void reset_prepare_engine(struct intel_engine_cs *engine)
+static bool reset_prepare_engine(struct intel_engine_cs *engine)
 {
+	bool awake;
+
 	/*
 	 * During the reset sequence, we must prevent the engine from
 	 * entering RC6. As the context state is undefined until we restart
@@ -678,9 +680,12 @@ static void reset_prepare_engine(struct intel_engine_cs *engine)
 	 * written to the powercontext is undefined and so we may lose
 	 * GPU state upon resume, i.e. fail to restart after a reset.
 	 */
-	intel_engine_pm_get(engine);
 	intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL);
+	awake = intel_engine_pm_get_if_awake(engine);
+
 	engine->reset.prepare(engine);
+
+	return awake;
 }
 
 static void revoke_mmaps(struct drm_i915_private *i915)
@@ -709,16 +714,20 @@ static void revoke_mmaps(struct drm_i915_private *i915)
 	}
 }
 
-static void reset_prepare(struct drm_i915_private *i915)
+static intel_engine_mask_t reset_prepare(struct drm_i915_private *i915)
 {
 	struct intel_engine_cs *engine;
+	intel_engine_mask_t awake = 0;
 	enum intel_engine_id id;
 
 	intel_gt_pm_get(i915);
 	for_each_engine(engine, i915, id)
-		reset_prepare_engine(engine);
+		if (reset_prepare_engine(engine))
+			awake |= engine->mask;
 
 	intel_uc_reset_prepare(i915);
+
+	return awake;
 }
 
 static void gt_revoke(struct drm_i915_private *i915)
@@ -749,20 +758,23 @@ static int gt_reset(struct drm_i915_private *i915,
 	return err;
 }
 
-static void reset_finish_engine(struct intel_engine_cs *engine)
+static void reset_finish_engine(struct intel_engine_cs *engine, bool awake)
 {
 	engine->reset.finish(engine);
-	intel_engine_pm_put(engine);
+	if (awake)
+		intel_engine_pm_put(engine);
+
 	intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL);
 }
 
-static void reset_finish(struct drm_i915_private *i915)
+static void reset_finish(struct drm_i915_private *i915,
+			 intel_engine_mask_t awake)
 {
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
 
 	for_each_engine(engine, i915, id) {
-		reset_finish_engine(engine);
+		reset_finish_engine(engine, awake & engine->mask);
 		intel_engine_signal_breadcrumbs(engine);
 	}
 	intel_gt_pm_put(i915);
@@ -789,6 +801,7 @@ static void __i915_gem_set_wedged(struct drm_i915_private *i915)
 {
 	struct i915_gpu_error *error = &i915->gpu_error;
 	struct intel_engine_cs *engine;
+	intel_engine_mask_t awake;
 	enum intel_engine_id id;
 
 	if (test_bit(I915_WEDGED, &error->flags))
@@ -808,7 +821,7 @@ static void __i915_gem_set_wedged(struct drm_i915_private *i915)
 	 * rolling the global seqno forward (since this would complete requests
 	 * for which we haven't set the fence error to EIO yet).
 	 */
-	reset_prepare(i915);
+	awake = reset_prepare(i915);
 
 	/* Even if the GPU reset fails, it should still stop the engines */
 	if (!INTEL_INFO(i915)->gpu_reset_clobbers_display)
@@ -832,7 +845,7 @@ static void __i915_gem_set_wedged(struct drm_i915_private *i915)
 	for_each_engine(engine, i915, id)
 		engine->cancel_requests(engine);
 
-	reset_finish(i915);
+	reset_finish(i915, awake);
 
 	GEM_TRACE("end\n");
 }
@@ -964,6 +977,7 @@ void i915_reset(struct drm_i915_private *i915,
 		const char *reason)
 {
 	struct i915_gpu_error *error = &i915->gpu_error;
+	intel_engine_mask_t awake;
 	int ret;
 
 	GEM_TRACE("flags=%lx\n", error->flags);
@@ -980,7 +994,7 @@ void i915_reset(struct drm_i915_private *i915,
 		dev_notice(i915->drm.dev, "Resetting chip for %s\n", reason);
 	error->reset_count++;
 
-	reset_prepare(i915);
+	awake = reset_prepare(i915);
 
 	if (!intel_has_gpu_reset(i915)) {
 		if (i915_modparams.reset)
@@ -1021,7 +1035,7 @@ void i915_reset(struct drm_i915_private *i915,
 	i915_queue_hangcheck(i915);
 
 finish:
-	reset_finish(i915);
+	reset_finish(i915, awake);
 unlock:
 	mutex_unlock(&error->wedge_mutex);
 	return;
@@ -1067,7 +1081,8 @@ static inline int intel_gt_reset_engine(struct drm_i915_private *i915,
 int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
 {
 	struct i915_gpu_error *error = &engine->i915->gpu_error;
-	int ret;
+	int ret = 0;
+	bool awake;
 
 	GEM_TRACE("%s flags=%lx\n", engine->name, error->flags);
 	GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
@@ -1075,7 +1090,9 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
 	if (!intel_engine_is_awake(engine))
 		return 0;
 
-	reset_prepare_engine(engine);
+	awake = reset_prepare_engine(engine);
+	if (!awake)
+		goto finish;
 
 	if (msg)
 		dev_notice(engine->i915->drm.dev,
@@ -1112,7 +1129,8 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg)
 
 out:
 	intel_engine_cancel_stop_cs(engine);
-	reset_finish_engine(engine);
+finish:
+	reset_finish_engine(engine, awake);
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/selftest_reset.c b/drivers/gpu/drm/i915/gt/selftest_reset.c
index 89da9e7cc1ba..f173a264bb59 100644
--- a/drivers/gpu/drm/i915/gt/selftest_reset.c
+++ b/drivers/gpu/drm/i915/gt/selftest_reset.c
@@ -71,12 +71,16 @@ static int igt_atomic_reset(void *arg)
 		goto unlock;
 
 	for (p = igt_atomic_phases; p->name; p++) {
+		intel_engine_mask_t awake;
+
 		GEM_TRACE("intel_gpu_reset under %s\n", p->name);
 
 		p->critical_section_begin();
-		reset_prepare(i915);
+		awake = reset_prepare(i915);
+
 		err = intel_gpu_reset(i915, ALL_ENGINES);
-		reset_finish(i915);
+
+		reset_finish(i915, awake);
 		p->critical_section_end();
 
 		if (err) {
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list