[Intel-gfx] [PATCH 2/2] drm/i915/gt: preempt and reset based on reset domain

Tejas Upadhyay tejaskumarx.surendrakumar.upadhyay at intel.com
Wed Mar 16 13:07:54 UTC 2022


When we have shared reset domains, as we the engine
may be indirectly coupled to the stalled engine, and
we need to idle the current context to prevent
collateral damage.

Suggested-by: Chris Wilson <chris at chris-wilson.co.uk>
Signed-off-by: Tejas Upadhyay <tejaskumarx.surendrakumar.upadhyay at intel.com>
---
 drivers/gpu/drm/i915/gt/intel_engine.h               | 3 ++-
 drivers/gpu/drm/i915/gt/intel_engine_cs.c            | 6 ++++++
 drivers/gpu/drm/i915/gt/intel_engine_types.h         | 8 ++++++++
 drivers/gpu/drm/i915/gt/intel_execlists_submission.c | 7 ++++++-
 drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c  | 2 +-
 drivers/gpu/drm/i915/gt/selftest_execlists.c         | 4 ++--
 drivers/gpu/drm/i915/selftests/i915_request.c        | 5 ++---
 7 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
index 1c0ab05c3c40..a6ea0cdd8b53 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -282,7 +282,8 @@ intel_engine_has_preempt_reset(const struct intel_engine_cs *engine)
 	if (!CONFIG_DRM_I915_PREEMPT_TIMEOUT)
 		return false;
 
-	return intel_engine_has_preemption(engine);
+	return intel_engine_has_preemption(engine) &&
+	       !intel_engine_has_shared_reset_domain(engine);
 }
 
 #define FORCE_VIRTUAL	BIT(0)
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 8080479f27aa..b28120f0158a 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -472,7 +472,13 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
 static void __setup_engine_capabilities(struct intel_engine_cs *engine)
 {
 	struct drm_i915_private *i915 = engine->i915;
+	enum intel_engine_id id;
+	struct intel_engine_cs *e;
 
+	for_each_engine(e, engine->gt, id)
+		if ((e->reset_domain & engine->reset_domain) &&
+		    e->id != engine->id)
+			engine->flags |= I915_ENGINE_HAS_SHARED_RESET_DOMAIN;
 	if (engine->class == VIDEO_DECODE_CLASS) {
 		/*
 		 * HEVC support is present on first engine instance
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 194155de900d..d27103b23318 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -531,6 +531,8 @@ struct intel_engine_cs {
 #define I915_ENGINE_HAS_RCS_REG_STATE  BIT(9)
 #define I915_ENGINE_HAS_EU_PRIORITY    BIT(10)
 #define I915_ENGINE_FIRST_RENDER_COMPUTE BIT(11)
+#define I915_ENGINE_HAS_SHARED_RESET_DOMAIN BIT(9)
+
 	unsigned int flags;
 
 	/*
@@ -598,6 +600,12 @@ intel_engine_supports_stats(const struct intel_engine_cs *engine)
 	return engine->flags & I915_ENGINE_SUPPORTS_STATS;
 }
 
+static inline bool
+intel_engine_has_shared_reset_domain(const struct intel_engine_cs *engine)
+{
+	return engine->flags & I915_ENGINE_HAS_SHARED_RESET_DOMAIN;
+}
+
 static inline bool
 intel_engine_has_preemption(const struct intel_engine_cs *engine)
 {
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 006e2d9a53e3..9dda02956494 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -2461,6 +2461,9 @@ static int execlists_suspend(struct intel_engine_cs *engine)
 	unsigned long timeout;
 	int err;
 
+	if (!intel_engine_pm_get_if_awake(engine))
+		return 0;
+	ENGINE_TRACE(engine, "supending active engine\n");
 	/* Stop further submissions, but listen for our own preempt-to-idle */
 	tasklet_disable(&se->tasklet);
 	se->tasklet.callback = suspend_tasklet;
@@ -2524,12 +2527,14 @@ static int execlists_suspend(struct intel_engine_cs *engine)
 		}
 	}
 
-	return 0;
+	goto out;
 
 err:
 	tasklet_disable(&se->tasklet);
 	se->tasklet.callback = execlists_submission_tasklet;
 	tasklet_enable(&se->tasklet);
+out:
+	intel_engine_pm_put(engine);
 	return err;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c b/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c
index 273d440a53e3..939bbea7ce1b 100644
--- a/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c
+++ b/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c
@@ -356,7 +356,7 @@ static int live_heartbeat_off(void *arg)
 		return 0;
 
 	for_each_engine(engine, gt, id) {
-		if (!intel_engine_has_preemption(engine))
+		if (!intel_engine_has_preempt_reset(engine))
 			continue;
 
 		err = __live_heartbeat_off(engine);
diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c
index 09f8cd2d0e2c..3eb3496cfb7e 100644
--- a/drivers/gpu/drm/i915/gt/selftest_execlists.c
+++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c
@@ -2389,7 +2389,7 @@ static int live_preempt_cancel(void *arg)
 		goto err_client_a;
 
 	for_each_engine(data.engine, gt, id) {
-		if (!intel_engine_has_preemption(data.engine))
+		if (!intel_engine_has_preempt_reset(data.engine))
 			continue;
 
 		err = __cancel_active0(&data);
@@ -3399,7 +3399,7 @@ static int live_preempt_timeout(void *arg)
 		unsigned long saved_timeout;
 		struct i915_request *rq;
 
-		if (!intel_engine_has_preemption(engine))
+		if (!intel_engine_has_preempt_reset(engine))
 			continue;
 
 		rq = spinner_create_request(&spin_lo, ctx_lo, engine,
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
index c56a0c2cd2f7..e80363c81d6b 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -803,8 +803,7 @@ static int __cancel_reset(struct drm_i915_private *i915,
 	unsigned long preempt_timeout_ms;
 	int err = 0;
 
-	if (!CONFIG_DRM_I915_PREEMPT_TIMEOUT ||
-	    !intel_has_reset_engine(engine->gt))
+	if (!intel_engine_has_preempt_reset(engine))
 		return 0;
 
 	preempt_timeout_ms = engine->props.preempt_timeout_ms;
@@ -906,7 +905,7 @@ static int live_cancel_request(void *arg)
 		struct igt_live_test t;
 		int err, err2;
 
-		if (!intel_engine_has_preemption(engine))
+		if (!intel_engine_has_preempt_reset(engine))
 			continue;
 
 		err = igt_live_test_begin(&t, i915, __func__, engine->name);
-- 
2.34.1



More information about the Intel-gfx mailing list