* [RFC 1/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 1)
2026-10-29 1:41 [RFC 0/5] Selftests fixes for multi-gt platforms in i915 Krzysztof Niemiec
@ 2026-10-29 1:41 ` Krzysztof Niemiec
2026-10-29 2:09 ` sashiko-bot
2026-10-29 1:41 ` [RFC 2/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 2) Krzysztof Niemiec
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Krzysztof Niemiec @ 2026-10-29 1:41 UTC (permalink / raw)
To: dri-devel, intel-gfx
Cc: Krzysztof Karas, Sebastian Brzezinka, Janusz Krzysztofik,
Andi Shyti, Krzysztof Niemiec
Port tests that take GT as argument or otherwise depend on a specific GT
to work to correctly check every GT on system.
This patch addresses the test suites that only really needed to have the
test calls wrapped inside for_each_gt with little to no other intervention.
Signed-off-by: Krzysztof Niemiec <krzysztof.niemiec@intel.com>
---
Note that the mock device related tests haven't been touched. This is
because the mock device is hard-coded to have a single GT, so to_gt()
will always be correct. At this moment the single GT assumption is
reasonable to make from the perspective of the test developer, and
changing those to handle multi-gt mock devices is IMO out of scope and
should be done if/when mock devices are expanded to have multiple GTs.
Maybe it's worth it to annotate the places where the single GT
assumption is made for mock devices?
.../drm/i915/gem/selftests/i915_gem_migrate.c | 11 +++++-
drivers/gpu/drm/i915/gt/selftest_context.c | 16 ++++++--
drivers/gpu/drm/i915/gt/selftest_engine.c | 15 +++++---
drivers/gpu/drm/i915/gt/selftest_engine_cs.c | 15 ++++++--
.../drm/i915/gt/selftest_engine_heartbeat.c | 22 +++++++----
drivers/gpu/drm/i915/gt/selftest_execlists.c | 19 +++++++---
drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 15 ++++++--
drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 24 +++++++-----
drivers/gpu/drm/i915/gt/selftest_lrc.c | 11 +++++-
drivers/gpu/drm/i915/gt/selftest_migrate.c | 38 +++++++++++++------
drivers/gpu/drm/i915/gt/selftest_mocs.c | 11 +++++-
drivers/gpu/drm/i915/gt/selftest_reset.c | 20 +++++++---
.../drm/i915/gt/selftest_ring_submission.c | 15 ++++++--
drivers/gpu/drm/i915/gt/selftest_timeline.c | 15 ++++++--
.../gpu/drm/i915/gt/selftest_workarounds.c | 15 ++++++--
drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 20 +++++++---
.../drm/i915/gt/uc/selftest_guc_hangcheck.c | 20 +++++++---
.../drm/i915/gt/uc/selftest_guc_multi_lrc.c | 20 +++++++---
.../gpu/drm/i915/selftests/i915_gem_evict.c | 15 ++++++--
drivers/gpu/drm/i915/selftests/intel_uncore.c | 11 +++++-
20 files changed, 260 insertions(+), 88 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
index d8f4a10d71de..3d4ffca8087c 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_migrate.c
@@ -520,9 +520,18 @@ int i915_gem_migrate_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_lmem_pages_failsafe_migrate),
SUBTEST(igt_lmem_async_migrate),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
if (!HAS_LMEM(i915))
return 0;
- return intel_gt_live_subtests(tests, to_gt(i915));
+ for_each_gt(gt, i915, id) {
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c
index ab76703f6e8b..ae56b410a320 100644
--- a/drivers/gpu/drm/i915/gt/selftest_context.c
+++ b/drivers/gpu/drm/i915/gt/selftest_context.c
@@ -446,10 +446,18 @@ int intel_context_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_active_context),
SUBTEST(live_remote_context),
};
- struct intel_gt *gt = to_gt(i915);
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(gt))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
+
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
- return intel_gt_live_subtests(tests, gt);
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_engine.c b/drivers/gpu/drm/i915/gt/selftest_engine.c
index 57fea9ea1705..bd96db071859 100644
--- a/drivers/gpu/drm/i915/gt/selftest_engine.c
+++ b/drivers/gpu/drm/i915/gt/selftest_engine.c
@@ -12,15 +12,18 @@ int intel_engine_live_selftests(struct drm_i915_private *i915)
live_engine_pm_selftests,
NULL,
};
- struct intel_gt *gt = to_gt(i915);
+ struct intel_gt *gt;
typeof(*tests) *fn;
+ unsigned int id;
- for (fn = tests; *fn; fn++) {
- int err;
+ for_each_gt(gt, i915, id) {
+ for (fn = tests; *fn; fn++) {
+ int err;
- err = (*fn)(gt);
- if (err)
- return err;
+ err = (*fn)(gt);
+ if (err)
+ return err;
+ }
}
return 0;
diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_cs.c b/drivers/gpu/drm/i915/gt/selftest_engine_cs.c
index 5ffa5e30f419..99348395b92b 100644
--- a/drivers/gpu/drm/i915/gt/selftest_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/selftest_engine_cs.c
@@ -380,11 +380,20 @@ int intel_engine_cs_perf_selftests(struct drm_i915_private *i915)
SUBTEST(perf_mi_bb_start),
SUBTEST(perf_mi_noop),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
- return intel_gt_live_subtests(tests, to_gt(i915));
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
static int intel_mmio_bases_check(void *arg)
diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c b/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c
index b893a8fde895..933f30d250c7 100644
--- a/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c
+++ b/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c
@@ -266,18 +266,26 @@ int intel_heartbeat_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_heartbeat_off),
};
int saved_hangcheck;
+ struct intel_gt *gt;
+ unsigned int id;
int err;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
- saved_hangcheck = i915->params.enable_hangcheck;
- i915->params.enable_hangcheck = INT_MAX;
+ saved_hangcheck = i915->params.enable_hangcheck;
+ i915->params.enable_hangcheck = INT_MAX;
- err = intel_gt_live_subtests(tests, to_gt(i915));
+ err = intel_gt_live_subtests(tests, gt);
- i915->params.enable_hangcheck = saved_hangcheck;
- return err;
+ i915->params.enable_hangcheck = saved_hangcheck;
+
+ if (err)
+ return err;
+ }
+
+ return 0;
}
void st_engine_heartbeat_disable(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c
index 21e5ed9f72a3..ddf71b3784bf 100644
--- a/drivers/gpu/drm/i915/gt/selftest_execlists.c
+++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c
@@ -4495,12 +4495,21 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_virtual_slice),
SUBTEST(live_virtual_reset),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (to_gt(i915)->submission_method != INTEL_SUBMISSION_ELSP)
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (gt->submission_method != INTEL_SUBMISSION_ELSP)
+ continue;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ if (intel_gt_is_wedged(gt))
+ continue;
- return intel_gt_live_subtests(tests, to_gt(i915));
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
index 07eaf71955c4..09c0c4096665 100644
--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
@@ -205,9 +205,18 @@ int intel_gt_pm_late_selftests(struct drm_i915_private *i915)
*/
SUBTEST(live_rc6_ctx_wa),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
- return intel_gt_live_subtests(tests, to_gt(i915));
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
index 53f3ce5c33a4..d67a6d75c56a 100644
--- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
@@ -2016,21 +2016,27 @@ int intel_hangcheck_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_reset_evict_fence),
SUBTEST(igt_handle_error),
};
- struct intel_gt *gt = to_gt(i915);
intel_wakeref_t wakeref;
+ struct intel_gt *gt;
+ unsigned int id;
int err;
- if (!intel_has_gpu_reset(gt))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (!intel_has_gpu_reset(gt))
+ continue;
- if (intel_gt_is_wedged(gt))
- return -EIO; /* we're long past hope of a successful reset */
+ if (intel_gt_is_wedged(gt))
+ return -EIO; /* we're long past hope of a successful reset */
- wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+ wakeref = intel_runtime_pm_get(gt->uncore->rpm);
- err = intel_gt_live_subtests(tests, gt);
+ err = intel_gt_live_subtests(tests, gt);
- intel_runtime_pm_put(gt->uncore->rpm, wakeref);
+ intel_runtime_pm_put(gt->uncore->rpm, wakeref);
- return err;
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c b/drivers/gpu/drm/i915/gt/selftest_lrc.c
index 23f04f6f8fba..ac26c91b1e1f 100644
--- a/drivers/gpu/drm/i915/gt/selftest_lrc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_lrc.c
@@ -1986,9 +1986,18 @@ int intel_lrc_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_lrc_indirect_ctx_bb),
SUBTEST(live_lrc_per_ctx_bb),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
if (!HAS_LOGICAL_RING_CONTEXTS(i915))
return 0;
- return intel_gt_live_subtests(tests, to_gt(i915));
+ for_each_gt(gt, i915, id) {
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_migrate.c b/drivers/gpu/drm/i915/gt/selftest_migrate.c
index 5b986a7687d9..997fd1ec155c 100644
--- a/drivers/gpu/drm/i915/gt/selftest_migrate.c
+++ b/drivers/gpu/drm/i915/gt/selftest_migrate.c
@@ -562,7 +562,7 @@ static int live_emit_pte_full_ring(void *arg)
* nearly full.
*/
- if (igt_spinner_init(&st.spin, to_gt(i915)))
+ if (igt_spinner_init(&st.spin, gt))
return -ENOMEM;
obj = i915_gem_object_create_internal(i915, 2 * PAGE_SIZE);
@@ -806,12 +806,20 @@ int intel_migrate_live_selftests(struct drm_i915_private *i915)
SUBTEST(thread_global_copy),
SUBTEST(thread_global_clear),
};
- struct intel_gt *gt = to_gt(i915);
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (!gt->migrate.context)
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (!gt->migrate.context)
+ continue;
- return intel_gt_live_subtests(tests, gt);
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
static struct drm_i915_gem_object *
@@ -1027,13 +1035,21 @@ int intel_migrate_perf_selftests(struct drm_i915_private *i915)
SUBTEST(perf_clear_blt),
SUBTEST(perf_copy_blt),
};
- struct intel_gt *gt = to_gt(i915);
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(gt))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
- if (!gt->migrate.context)
- return 0;
+ if (!gt->migrate.context)
+ continue;
- return intel_gt_live_subtests(tests, gt);
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_mocs.c b/drivers/gpu/drm/i915/gt/selftest_mocs.c
index d73e438fb85f..916ceba580da 100644
--- a/drivers/gpu/drm/i915/gt/selftest_mocs.c
+++ b/drivers/gpu/drm/i915/gt/selftest_mocs.c
@@ -445,9 +445,18 @@ int intel_mocs_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_mocs_reset),
};
struct drm_i915_mocs_table table;
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
if (!get_mocs_settings(i915, &table))
return 0;
- return intel_gt_live_subtests(tests, to_gt(i915));
+ for_each_gt(gt, i915, id) {
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_reset.c b/drivers/gpu/drm/i915/gt/selftest_reset.c
index 2cfc23c58e90..43f90b0687d7 100644
--- a/drivers/gpu/drm/i915/gt/selftest_reset.c
+++ b/drivers/gpu/drm/i915/gt/selftest_reset.c
@@ -382,13 +382,21 @@ int intel_reset_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_atomic_reset),
SUBTEST(igt_atomic_engine_reset),
};
- struct intel_gt *gt = to_gt(i915);
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (!intel_has_gpu_reset(gt))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (!intel_has_gpu_reset(gt))
+ continue;
- if (intel_gt_is_wedged(gt))
- return -EIO; /* we're long past hope of a successful reset */
+ if (intel_gt_is_wedged(gt))
+ return -EIO; /* we're long past hope of a successful reset */
- return intel_gt_live_subtests(tests, gt);
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_ring_submission.c b/drivers/gpu/drm/i915/gt/selftest_ring_submission.c
index 600333ae6c8c..6ce7be6e7692 100644
--- a/drivers/gpu/drm/i915/gt/selftest_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/selftest_ring_submission.c
@@ -291,9 +291,18 @@ int intel_ring_submission_live_selftests(struct drm_i915_private *i915)
static const struct i915_subtest tests[] = {
SUBTEST(live_ctx_switch_wa),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (to_gt(i915)->submission_method > INTEL_SUBMISSION_RING)
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (gt->submission_method > INTEL_SUBMISSION_RING)
+ continue;
- return intel_gt_live_subtests(tests, to_gt(i915));
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c
index 29d860a5c9c8..0aad7bd50926 100644
--- a/drivers/gpu/drm/i915/gt/selftest_timeline.c
+++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c
@@ -1421,9 +1421,18 @@ int intel_timeline_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_hwsp_rollover_kernel),
SUBTEST(live_hwsp_rollover_user),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
- return intel_gt_live_subtests(tests, to_gt(i915));
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_workarounds.c b/drivers/gpu/drm/i915/gt/selftest_workarounds.c
index 4e4c420ae67f..8f9705b25f70 100644
--- a/drivers/gpu/drm/i915/gt/selftest_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/selftest_workarounds.c
@@ -1374,9 +1374,18 @@ int intel_workarounds_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_gpu_reset_workarounds),
SUBTEST(live_engine_reset_workarounds),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
+
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
- return intel_gt_live_subtests(tests, to_gt(i915));
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
index 63a75272924f..c8ce82692614 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
@@ -407,13 +407,21 @@ int intel_guc_live_selftests(struct drm_i915_private *i915)
SUBTEST(intel_guc_steal_guc_ids),
SUBTEST(intel_guc_fast_request),
};
- struct intel_gt *gt = to_gt(i915);
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(gt))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
- if (!intel_uc_uses_guc_submission(>->uc))
- return 0;
+ if (!intel_uc_uses_guc_submission(>->uc))
+ continue;
+
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
- return intel_gt_live_subtests(tests, gt);
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
index 83801c992488..91a129e73665 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
@@ -150,13 +150,21 @@ int intel_guc_hang_check(struct drm_i915_private *i915)
static const struct i915_subtest tests[] = {
SUBTEST(intel_hang_guc),
};
- struct intel_gt *gt = to_gt(i915);
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(gt))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
- if (!intel_uc_uses_guc_submission(>->uc))
- return 0;
+ if (!intel_uc_uses_guc_submission(>->uc))
+ continue;
+
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
- return intel_gt_live_subtests(tests, gt);
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c b/drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c
index 18077801b2e6..e4652b1b303d 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc_multi_lrc.c
@@ -172,13 +172,21 @@ int intel_guc_multi_lrc_live_selftests(struct drm_i915_private *i915)
static const struct i915_subtest tests[] = {
SUBTEST(intel_guc_multi_lrc_basic),
};
- struct intel_gt *gt = to_gt(i915);
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(gt))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
- if (!intel_uc_uses_guc_submission(>->uc))
- return 0;
+ if (!intel_uc_uses_guc_submission(>->uc))
+ continue;
- return intel_gt_live_subtests(tests, gt);
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
index 718cddde7e73..fd58faf31fe5 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
@@ -563,9 +563,18 @@ int i915_gem_evict_live_selftests(struct drm_i915_private *i915)
static const struct i915_subtest tests[] = {
SUBTEST(igt_evict_contexts),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ continue;
+
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
- return intel_gt_live_subtests(tests, to_gt(i915));
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c
index 514d2200751b..e741dd322537 100644
--- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -288,6 +288,15 @@ int intel_uncore_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_fw_table),
SUBTEST(live_forcewake_ops),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- return intel_gt_live_subtests(tests, to_gt(i915));
+ for_each_gt(gt, i915, id) {
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [RFC 1/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 1)
2026-10-29 1:41 ` [RFC 1/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 1) Krzysztof Niemiec
@ 2026-10-29 2:09 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-10-29 2:09 UTC (permalink / raw)
To: Krzysztof Niemiec, dri-devel, intel-gfx
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] drm/i915/selftests: hang_init() uses UABI-only GT0 context in multi-GT loop
- [Medium] drm/i915/selftests: GT mismatch in selftest_execlists spinner contexts
- [Medium] drm/i915/selftests: missing gsi_offset in __live_rc6_ctx() on media GT
--
commit 39fe8a3841172dae27e66c85ef1663181f7d0e43
Author: Krzysztof Niemiec <krzysztof.niemiec@intel.com>
drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 1)
This patch wraps several GT-dependent live and performance selftest suites in
for_each_gt() loops so that they run against all GTs present on the system
rather than only the primary GT.
[ ... ]
> diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c
> index 21e5ed9f72a30..ddf71b3784bf7 100644
> --- a/drivers/gpu/drm/i915/gt/selftest_execlists.c
> +++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c
> @@ -4495,12 +4495,21 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915)
> SUBTEST(live_virtual_slice),
> SUBTEST(live_virtual_reset),
> };
> + struct intel_gt *gt;
> + unsigned int id;
> + int err;
>
> - if (to_gt(i915)->submission_method != INTEL_SUBMISSION_ELSP)
> - return 0;
> + for_each_gt(gt, i915, id) {
> + if (gt->submission_method != INTEL_SUBMISSION_ELSP)
> + continue;
>
> - if (intel_gt_is_wedged(to_gt(i915)))
> - return 0;
> + if (intel_gt_is_wedged(gt))
> + continue;
>
> - return intel_gt_live_subtests(tests, to_gt(i915));
> + err = intel_gt_live_subtests(tests, gt);
[Severity: Medium]
When intel_execlists_live_selftests() runs on a secondary GT where
gt != to_gt(i915), won't several preemption subtests trigger a GEM_BUG_ON()
in igt_spinner_create_request()?
Specifically, live_preempt(), live_late_preempt(), live_preempt_timeout(),
and preempt_client_init() (used by live_nopreempt(), live_preempt_cancel(),
live_suppress_self_preempt(), and live_chain_preempt()) create GEM contexts
with a NULL vm while initializing their spinners on gt:
drivers/gpu/drm/i915/gt/selftest_execlists.c:live_preempt() {
...
ctx_hi = kernel_context(gt->i915, NULL);
if (!ctx_hi)
return -ENOMEM;
ctx_hi->sched.priority = I915_CONTEXT_MAX_USER_PRIORITY;
ctx_lo = kernel_context(gt->i915, NULL);
if (!ctx_lo)
goto err_ctx_hi;
ctx_lo->sched.priority = I915_CONTEXT_MIN_USER_PRIORITY;
if (igt_spinner_init(&spin_hi, gt))
goto err_ctx_lo;
...
}
When kernel_context(gt->i915, NULL) calls i915_gem_create_context() with
pc->vm == NULL, the context VM is created on to_gt(i915) rather than gt:
drivers/gpu/drm/i915/gem/i915_gem_context.c:i915_gem_create_context() {
...
if (pc->vm) {
vm = i915_vm_get(pc->vm);
} else if (HAS_FULL_PPGTT(i915)) {
struct i915_ppgtt *ppgtt;
ppgtt = i915_ppgtt_create(to_gt(i915), 0);
...
}
When those subtests then call
spinner_create_request() -> igt_spinner_create_request(spin, ce, arb),
spin->gt is gt while ce->vm->gt is to_gt(i915), hitting:
drivers/gpu/drm/i915/selftests/igt_spinner.c:igt_spinner_create_request() {
...
GEM_BUG_ON(spin->gt != ce->vm->gt);
...
}
> diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
> index 07eaf71955c44..09c0c4096665a 100644
> --- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
> +++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
> @@ -205,9 +205,18 @@ int intel_gt_pm_late_selftests(struct drm_i915_private *i915)
> */
> SUBTEST(live_rc6_ctx_wa),
> };
> + struct intel_gt *gt;
> + unsigned int id;
> + int err;
>
> - if (intel_gt_is_wedged(to_gt(i915)))
> - return 0;
> + for_each_gt(gt, i915, id) {
> + if (intel_gt_is_wedged(gt))
> + continue;
>
> - return intel_gt_live_subtests(tests, to_gt(i915));
> + err = intel_gt_live_subtests(tests, gt);
[Severity: Medium]
Now that intel_gt_pm_late_selftests() runs live_rc6_ctx_wa() on every GT,
does __live_rc6_ctx() read the wrong MMIO offset when executing on a
standalone media GT?
In drivers/gpu/drm/i915/gt/selftest_rc6.c, __live_rc6_ctx() emits an
MI_STORE_REGISTER_MEM command for GEN8_RC6_CTX_INFO without adding
ce->engine->gt->uncore->gsi_offset:
drivers/gpu/drm/i915/gt/selftest_rc6.c:__live_rc6_ctx() {
...
*cs++ = cmd;
*cs++ = i915_mmio_reg_offset(GEN8_RC6_CTX_INFO);
*cs++ = ce->timeline->hwsp_offset + 8;
*cs++ = 0;
...
}
On platforms with a standalone media GT (where uncore->gsi_offset is
0x380000), won't the media engine command streamer read the primary GT's
GEN8_RC6_CTX_INFO register at 0x8504 instead of the media GT's register at
0x388504?
> diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
> index 53f3ce5c33a47..d67a6d75c56a4 100644
> --- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
> +++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
> @@ -2016,21 +2016,27 @@ int intel_hangcheck_live_selftests(struct drm_i915_private *i915)
> SUBTEST(igt_reset_evict_fence),
> SUBTEST(igt_handle_error),
> };
> - struct intel_gt *gt = to_gt(i915);
> intel_wakeref_t wakeref;
> + struct intel_gt *gt;
> + unsigned int id;
> int err;
>
> - if (!intel_has_gpu_reset(gt))
> - return 0;
> + for_each_gt(gt, i915, id) {
> + if (!intel_has_gpu_reset(gt))
> + continue;
>
> - if (intel_gt_is_wedged(gt))
> - return -EIO; /* we're long past hope of a successful reset */
> + if (intel_gt_is_wedged(gt))
> + return -EIO; /* we're long past hope of a successful reset */
>
> - wakeref = intel_runtime_pm_get(gt->uncore->rpm);
> + wakeref = intel_runtime_pm_get(gt->uncore->rpm);
>
> - err = intel_gt_live_subtests(tests, gt);
> + err = intel_gt_live_subtests(tests, gt);
[Severity: Medium]
Can running intel_hangcheck_live_selftests() across all GTs cause subtests
such as igt_hang_sanitycheck(), igt_reset_active_engine(),
igt_reset_engines(), and igt_reset_queue() to fail with -EINVAL on secondary
GTs that have non-UABI engines like GSC0?
In drivers/gpu/drm/i915/gt/selftest_hangcheck.c, hang_init() sets up h->ctx
via kernel_context(gt->i915, NULL):
drivers/gpu/drm/i915/gt/selftest_hangcheck.c:hang_init() {
...
h->ctx = kernel_context(gt->i915, NULL);
if (IS_ERR(h->ctx))
return PTR_ERR(h->ctx);
...
}
Because vm is NULL, i915_gem_create_context() allocates h->ctx->vm on
to_gt(i915) instead of gt, and populates h->ctx->engines via
default_engines() using only for_each_uabi_engine(). Non-UABI engines such as
GSC0 on the standalone media GT (which has uabi_class == I915_NO_UABI_CLASS)
are skipped in intel_engines_driver_register(), leaving engine->legacy_idx as
INVALID_ENGINE (-1).
When the hangcheck subtests iterate over all engines on the GT with
for_each_engine(engine, gt, id) and call hang_create_request(&h, engine) on
GSC0:
drivers/gpu/drm/i915/gt/selftest_hangcheck.c:hang_create_request() {
...
rq = igt_request_alloc(h->ctx, engine);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto unpin_hws;
}
...
}
igt_request_alloc() looks up engine->legacy_idx in h->ctx:
drivers/gpu/drm/i915/gem/selftests/igt_gem_utils.c:igt_request_alloc() {
...
ce = i915_gem_context_get_engine(ctx, engine->legacy_idx);
if (IS_ERR(ce))
return ERR_CAST(ce);
...
}
Should hang_init() pass gt->vm to kernel_context(), and should the hangcheck
subtests either create per-engine contexts on gt or skip engines that are not
populated in h->ctx?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261029014155.55865-1-krzysztof.niemiec@intel.com?part=1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 2/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 2)
2026-10-29 1:41 [RFC 0/5] Selftests fixes for multi-gt platforms in i915 Krzysztof Niemiec
2026-10-29 1:41 ` [RFC 1/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 1) Krzysztof Niemiec
@ 2026-10-29 1:41 ` Krzysztof Niemiec
2026-10-29 1:56 ` sashiko-bot
2026-10-29 1:41 ` [RFC 3/5] drm/i915/selftests: Port i915_gem_gtt.c selftest file to multi-gt Krzysztof Niemiec
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Krzysztof Niemiec @ 2026-10-29 1:41 UTC (permalink / raw)
To: dri-devel, intel-gfx
Cc: Krzysztof Karas, Sebastian Brzezinka, Janusz Krzysztofik,
Andi Shyti, Krzysztof Niemiec
Some tests aren't passed a GT directly and don't reference them, but run
only under the condition of the GT not being wedged. Update the top-level
selftest functions of these tests to abort when some GT is wedged.
Signed-off-by: Krzysztof Niemiec <krzysztof.niemiec@intel.com>
---
I made an assumption here, that if ANY of the GTs are wedged, the test
should abort. It is of course possible to make it so that only if ALL
GTs are wedged, the test should abort. Former is probably safer but if
there's good arguments for the latter I can change it.
drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 8 ++++++--
drivers/gpu/drm/i915/selftests/i915_active.c | 8 ++++++--
drivers/gpu/drm/i915/selftests/i915_perf.c | 8 ++++++--
drivers/gpu/drm/i915/selftests/i915_request.c | 8 ++++++--
.../gpu/drm/i915/selftests/intel_memory_region.c | 16 ++++++++++++----
5 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 44718e728291..a8ae65ddb073 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -2012,14 +2012,18 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_ppgtt_huge_fill),
SUBTEST(igt_ppgtt_64K),
};
+ struct intel_gt *gt;
+ unsigned int id;
if (!HAS_PPGTT(i915)) {
pr_info("PPGTT not supported, skipping live-selftests\n");
return 0;
}
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ return 0;
+ }
return i915_live_subtests(tests, i915);
}
diff --git a/drivers/gpu/drm/i915/selftests/i915_active.c b/drivers/gpu/drm/i915/selftests/i915_active.c
index 9fea2fabeac4..4e1d3ccdf8c6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_active.c
+++ b/drivers/gpu/drm/i915/selftests/i915_active.c
@@ -256,9 +256,13 @@ int i915_active_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_active_retire),
SUBTEST(live_active_barrier),
};
+ struct intel_gt *gt;
+ unsigned int id;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ return 0;
+ }
return i915_subtests(tests, i915);
}
diff --git a/drivers/gpu/drm/i915/selftests/i915_perf.c b/drivers/gpu/drm/i915/selftests/i915_perf.c
index e9469e27f42a..e64d3b430994 100644
--- a/drivers/gpu/drm/i915/selftests/i915_perf.c
+++ b/drivers/gpu/drm/i915/selftests/i915_perf.c
@@ -425,13 +425,17 @@ int i915_perf_live_selftests(struct drm_i915_private *i915)
SUBTEST(live_noa_gpr),
};
struct i915_perf *perf = &i915->perf;
+ struct intel_gt *gt;
+ unsigned int id;
int err;
if (!perf->metrics_kobj || !perf->ops.enable_metric_set)
return 0;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ return 0;
+ }
err = alloc_empty_config(&i915->perf);
if (err)
diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
index e1a7c454a0a9..6bf8ba474497 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -3295,9 +3295,13 @@ int i915_request_perf_selftests(struct drm_i915_private *i915)
SUBTEST(perf_series_engines),
SUBTEST(perf_parallel_engines),
};
+ struct intel_gt *gt;
+ unsigned int id;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ return 0;
+ }
return i915_subtests(tests, i915);
}
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 8307390943a2..20f85db9e3f3 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -1380,14 +1380,18 @@ int intel_memory_region_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_lmem_write_cpu),
SUBTEST(igt_lmem_write_gpu),
};
+ struct intel_gt *gt;
+ unsigned int id;
if (!HAS_LMEM(i915)) {
pr_info("device lacks LMEM support, skipping\n");
return 0;
}
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ return 0;
+ }
return i915_live_subtests(tests, i915);
}
@@ -1397,9 +1401,13 @@ int intel_memory_region_perf_selftests(struct drm_i915_private *i915)
static const struct i915_subtest tests[] = {
SUBTEST(perf_memcpy),
};
+ struct intel_gt *gt;
+ unsigned int id;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ return 0;
+ }
return i915_live_subtests(tests, i915);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [RFC 2/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 2)
2026-10-29 1:41 ` [RFC 2/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 2) Krzysztof Niemiec
@ 2026-10-29 1:56 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-10-29 1:56 UTC (permalink / raw)
To: Krzysztof Niemiec, dri-devel, intel-gfx
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] drm/i915/selftests: unported wedged check in i915_request_live_selftests()
--
commit 46c0aca503dcff6d10a11b75ac8ca3cd05b6385a
Author: Krzysztof Niemiec <krzysztof.niemiec@intel.com>
drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 2)
This commit updates top-level i915 selftest entry points that do not take a GT
directly to check all GTs via for_each_gt() and abort if any GT is wedged.
[ ... ]
> diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c
> index e1a7c454a0a9d..6bf8ba4744974 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_request.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_request.c
> @@ -3295,9 +3295,13 @@ int i915_request_perf_selftests(struct drm_i915_private *i915)
> SUBTEST(perf_series_engines),
> SUBTEST(perf_parallel_engines),
> };
> + struct intel_gt *gt;
> + unsigned int id;
>
> - if (intel_gt_is_wedged(to_gt(i915)))
> - return 0;
> + for_each_gt(gt, i915, id) {
> + if (intel_gt_is_wedged(gt))
> + return 0;
> + }
[Severity: Medium]
Should i915_request_live_selftests() in
drivers/gpu/drm/i915/selftests/i915_request.c also be updated to iterate over
all GTs with for_each_gt() like i915_request_perf_selftests() here and
intel_memory_region_live_selftests() in
drivers/gpu/drm/i915/selftests/intel_memory_region.c?
Currently, i915_request_live_selftests() still checks only the primary GT:
int i915_request_live_selftests(struct drm_i915_private *i915)
{
...
if (intel_gt_is_wedged(to_gt(i915)))
return 0;
return i915_live_subtests(tests, i915);
}
Its subtests (such as live_nop_request(), live_all_engines(),
live_sequential_engines(), and live_parallel_engines()) do not reference
to_gt(i915) and instead iterate across all UABI engines on all GTs via
for_each_uabi_engine(), finishing with igt_live_test_end() ->
igt_flush_test().
If a secondary GT is wedged while GT0 is healthy,
i915_request_live_selftests() will not skip and will instead run against the
wedged GT's engines and fail with -EIO in igt_flush_test().
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261029014155.55865-1-krzysztof.niemiec@intel.com?part=2
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC 3/5] drm/i915/selftests: Port i915_gem_gtt.c selftest file to multi-gt
2026-10-29 1:41 [RFC 0/5] Selftests fixes for multi-gt platforms in i915 Krzysztof Niemiec
2026-10-29 1:41 ` [RFC 1/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 1) Krzysztof Niemiec
2026-10-29 1:41 ` [RFC 2/5] drm/i915/selftests: Port GT-dependent selftests to work with multi-GT (low-hanging fruits part 2) Krzysztof Niemiec
@ 2026-10-29 1:41 ` Krzysztof Niemiec
2026-10-29 1:41 ` [RFC 4/5] drm/i915/sefltests: Port i915_gem_context.c " Krzysztof Niemiec
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Krzysztof Niemiec @ 2026-10-29 1:41 UTC (permalink / raw)
To: dri-devel, intel-gfx
Cc: Krzysztof Karas, Sebastian Brzezinka, Janusz Krzysztofik,
Andi Shyti, Krzysztof Niemiec
Port the gtt selftets to test multiple GTs instead of just GT0. Mock
device tests stay on the to_gt() macro, as the mock device is hard-coded
to have a single gt at the point of writing the patch.
Signed-off-by: Krzysztof Niemiec <krzysztof.niemiec@intel.com>
---
Another assumption I made: we don't know anything a priori about any
shared GGTTs. This in truth is not really the case cause the multi-GT
platforms we do have in i915 do share a GGTT across GTs (namely GT_MEDIA
gets assigned GT0's GGTT). So the assumption can be strengthened at the
loss of genericity.
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 32 +++++++++++++------
1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index e6bd06774816..a2b8c1753daf 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -152,7 +152,8 @@ fake_dma_object(struct drm_i915_private *i915, u64 size)
static int igt_ppgtt_alloc(void *arg)
{
- struct drm_i915_private *dev_priv = arg;
+ struct intel_gt *gt = arg;
+ struct drm_i915_private *dev_priv = gt->i915;
struct i915_ppgtt *ppgtt;
struct i915_gem_ww_ctx ww;
u64 size, last, limit;
@@ -163,7 +164,7 @@ static int igt_ppgtt_alloc(void *arg)
if (!HAS_PPGTT(dev_priv))
return 0;
- ppgtt = i915_ppgtt_create(to_gt(dev_priv), 0);
+ ppgtt = i915_ppgtt_create(gt, 0);
if (IS_ERR(ppgtt))
return PTR_ERR(ppgtt);
@@ -1194,11 +1195,12 @@ static int misaligned_pin(struct i915_address_space *vm,
return 0;
}
-static int exercise_ppgtt(struct drm_i915_private *dev_priv,
+static int exercise_ppgtt(struct intel_gt *gt,
int (*func)(struct i915_address_space *vm,
u64 hole_start, u64 hole_end,
unsigned long end_time))
{
+ struct drm_i915_private *dev_priv = gt->i915;
struct i915_ppgtt *ppgtt;
IGT_TIMEOUT(end_time);
struct file *file;
@@ -1211,7 +1213,7 @@ static int exercise_ppgtt(struct drm_i915_private *dev_priv,
if (IS_ERR(file))
return PTR_ERR(file);
- ppgtt = i915_ppgtt_create(to_gt(dev_priv), 0);
+ ppgtt = i915_ppgtt_create(gt, 0);
if (IS_ERR(ppgtt)) {
err = PTR_ERR(ppgtt);
goto out_free;
@@ -1280,12 +1282,12 @@ static int sort_holes(void *priv, const struct list_head *A,
return 1;
}
-static int exercise_ggtt(struct drm_i915_private *i915,
+static int exercise_ggtt(struct intel_gt *gt,
int (*func)(struct i915_address_space *vm,
u64 hole_start, u64 hole_end,
unsigned long end_time))
{
- struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
+ struct i915_ggtt *ggtt = gt->ggtt;
u64 hole_start, hole_end, last = 0;
struct drm_mm_node *node;
IGT_TIMEOUT(end_time);
@@ -1349,8 +1351,9 @@ static int igt_ggtt_page(void *arg)
{
const unsigned int count = PAGE_SIZE/sizeof(u32);
I915_RND_STATE(prng);
- struct drm_i915_private *i915 = arg;
- struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
+ struct intel_gt *gt = arg;
+ struct drm_i915_private *i915 = gt->i915;
+ struct i915_ggtt *ggtt = gt->ggtt;
struct drm_i915_gem_object *obj;
intel_wakeref_t wakeref;
struct drm_mm_node tmp;
@@ -1976,8 +1979,17 @@ int i915_gem_gtt_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_ggtt_page),
SUBTEST(igt_ggtt_misaligned_pin),
};
+ struct intel_gt *gt;
+ uint32_t id;
+ int err;
- GEM_BUG_ON(offset_in_page(to_gt(i915)->ggtt->vm.total));
+ for_each_gt(gt, i915, id) {
+ GEM_BUG_ON(offset_in_page(gt->ggtt->vm.total));
- return i915_live_subtests(tests, i915);
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC 4/5] drm/i915/sefltests: Port i915_gem_context.c selftest file to multi-gt
2026-10-29 1:41 [RFC 0/5] Selftests fixes for multi-gt platforms in i915 Krzysztof Niemiec
` (2 preceding siblings ...)
2026-10-29 1:41 ` [RFC 3/5] drm/i915/selftests: Port i915_gem_gtt.c selftest file to multi-gt Krzysztof Niemiec
@ 2026-10-29 1:41 ` Krzysztof Niemiec
2026-10-29 1:41 ` [RFC 5/5] drm/i915/selftests: Port selftests that access ggtt to work with multi-gt Krzysztof Niemiec
2026-10-29 2:40 ` ✗ i915.CI.BAT: failure for Selftests fixes for multi-gt platforms in i915 Patchwork
5 siblings, 0 replies; 10+ messages in thread
From: Krzysztof Niemiec @ 2026-10-29 1:41 UTC (permalink / raw)
To: dri-devel, intel-gfx
Cc: Krzysztof Karas, Sebastian Brzezinka, Janusz Krzysztofik,
Andi Shyti, Krzysztof Niemiec
the __igt_ctx_sseu() function iterates over the engines in a system, but
only calls igt_global_reset_lock() on to_gt() (so GT0). Move the lock
deeper into the function such that the call is done for a specific
gt depending on which engine is currently being selected via engine->gt.
Signed-off-by: Krzysztof Niemiec <krzysztof.niemiec@intel.com>
---
This is opinionated as stated in the cover letter, the alternative way
to run this is to pass a GT to the test itself, and run it in a
for_each_gt loop, and then skip on engines that don't belong to the
currently processed GT.
Also same assumption as in patch 2, using essentially || instead of &&
for checking wedge.
.../drm/i915/gem/selftests/i915_gem_context.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
index 9d405098f9e7..afa170a4c740 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
@@ -1249,9 +1249,6 @@ __igt_ctx_sseu(struct drm_i915_private *i915,
if (GRAPHICS_VER(i915) < 9)
return 0;
- if (flags & TEST_RESET)
- igt_global_reset_lock(to_gt(i915));
-
obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
if (IS_ERR(obj)) {
ret = PTR_ERR(obj);
@@ -1295,6 +1292,9 @@ __igt_ctx_sseu(struct drm_i915_private *i915,
goto out_put;
}
+ if (flags & TEST_RESET)
+ igt_global_reset_lock(engine->gt);
+
ret = intel_context_pin(ce);
if (ret)
goto out_ce;
@@ -1323,6 +1323,8 @@ __igt_ctx_sseu(struct drm_i915_private *i915,
intel_context_unpin(ce);
out_ce:
intel_context_put(ce);
+ if (flags & TEST_RESET)
+ igt_global_reset_unlock(engine->gt);
} while (!ret);
if (igt_flush_test(i915))
@@ -1332,9 +1334,6 @@ __igt_ctx_sseu(struct drm_i915_private *i915,
i915_gem_object_put(obj);
out_unlock:
- if (flags & TEST_RESET)
- igt_global_reset_unlock(to_gt(i915));
-
if (ret)
pr_err("%s: Failed with %d!\n", name, ret);
@@ -1908,9 +1907,13 @@ int i915_gem_context_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_shared_ctx_exec),
SUBTEST(igt_vm_isolation),
};
+ struct intel_gt *gt;
+ unsigned int id;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ return 0;
+ }
return i915_live_subtests(tests, i915);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC 5/5] drm/i915/selftests: Port selftests that access ggtt to work with multi-gt
2026-10-29 1:41 [RFC 0/5] Selftests fixes for multi-gt platforms in i915 Krzysztof Niemiec
` (3 preceding siblings ...)
2026-10-29 1:41 ` [RFC 4/5] drm/i915/sefltests: Port i915_gem_context.c " Krzysztof Niemiec
@ 2026-10-29 1:41 ` Krzysztof Niemiec
2026-10-29 1:51 ` sashiko-bot
2026-10-29 2:40 ` ✗ i915.CI.BAT: failure for Selftests fixes for multi-gt platforms in i915 Patchwork
5 siblings, 1 reply; 10+ messages in thread
From: Krzysztof Niemiec @ 2026-10-29 1:41 UTC (permalink / raw)
To: dri-devel, intel-gfx
Cc: Krzysztof Karas, Sebastian Brzezinka, Janusz Krzysztofik,
Andi Shyti, Krzysztof Niemiec
Some of the selftests reference a GGTT via to_gt(i915)->ggtt. This is
only incidentally correct on single-gt platforms and on MTL and ARL,
which have two GTs sharing the same GGTT. In principle, however,
different GTs could have different GGTTs associated with them. Have the
tests reflect that scenario by switching to a specific gt instead of
using the to_gt() macro when appropriate.
Signed-off-by: Krzysztof Niemiec <krzysztof.niemiec@intel.com>
---
Same separate-GGTT assumption as in patch 3, however, this entire change
pertains only to this, so if that assumption can be relaxed, the entire
patch can be probably be dropped from the series (maybe save for the
engine->gt == gt check, but that can be squashed into another patch then)
.../i915/gem/selftests/i915_gem_client_blt.c | 29 +++++--
drivers/gpu/drm/i915/selftests/i915_gem.c | 79 +++++++++++--------
drivers/gpu/drm/i915/selftests/i915_vma.c | 16 +++-
3 files changed, 80 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
index 1d4d7cfb3f9c..938185274e29 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
@@ -688,11 +688,11 @@ static bool has_bit17_swizzle(int sw)
sw == I915_BIT_6_SWIZZLE_9_17);
}
-static bool bad_swizzling(struct drm_i915_private *i915)
+static bool bad_swizzling(struct intel_gt *gt)
{
- struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
+ struct i915_ggtt *ggtt = gt->ggtt;
- if (i915->gem_quirks & GEM_QUIRK_PIN_SWIZZLED_PAGES)
+ if (gt->i915->gem_quirks & GEM_QUIRK_PIN_SWIZZLED_PAGES)
return true;
if (has_bit17_swizzle(ggtt->bit_6_swizzle_x) ||
@@ -704,7 +704,8 @@ static bool bad_swizzling(struct drm_i915_private *i915)
static int igt_client_tiled_blits(void *arg)
{
- struct drm_i915_private *i915 = arg;
+ struct intel_gt *gt = arg;
+ struct drm_i915_private *i915 = gt->i915;
I915_RND_STATE(prng);
int inst = 0;
@@ -712,7 +713,7 @@ static int igt_client_tiled_blits(void *arg)
if (GRAPHICS_VER(i915) < 4)
return 0;
- if (bad_swizzling(i915)) /* Requires sane (sub-page) swizzling */
+ if (bad_swizzling(gt)) /* Requires sane (sub-page) swizzling */
return 0;
do {
@@ -725,6 +726,9 @@ static int igt_client_tiled_blits(void *arg)
if (!engine)
return 0;
+ if (engine->gt != gt)
+ continue;
+
err = __igt_client_tiled_blits(engine, &prng);
if (err == -ENODEV)
err = 0;
@@ -738,9 +742,18 @@ int i915_gem_client_blt_live_selftests(struct drm_i915_private *i915)
static const struct i915_subtest tests[] = {
SUBTEST(igt_client_tiled_blits),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ return 0;
- return i915_live_subtests(tests, i915);
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
+
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c b/drivers/gpu/drm/i915/selftests/i915_gem.c
index ad650f67114a..8f72fd1af8d6 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem.c
@@ -40,9 +40,10 @@ static int switch_to_context(struct i915_gem_context *ctx)
return err;
}
-static void trash_stolen(struct drm_i915_private *i915)
+static void trash_stolen(struct intel_gt *gt)
{
- struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
+ struct drm_i915_private *i915 = gt->i915;
+ struct i915_ggtt *ggtt = gt->ggtt;
const u64 slot = ggtt->error_capture.start;
const resource_size_t size = resource_size(&i915->dsm.stolen);
struct rnd_state prng;
@@ -74,11 +75,11 @@ static void trash_stolen(struct drm_i915_private *i915)
ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
}
-static void simulate_hibernate(struct drm_i915_private *i915)
+static void simulate_hibernate(struct intel_gt *gt)
{
intel_wakeref_t wakeref;
- wakeref = intel_runtime_pm_get(&i915->runtime_pm);
+ wakeref = intel_runtime_pm_get(>->i915->runtime_pm);
/*
* As a final string in the tail, invalidate stolen. Under a real S4,
@@ -87,9 +88,9 @@ static void simulate_hibernate(struct drm_i915_private *i915)
* for automated testing across a cluster), so to simulate the effect
* of stolen being trashed across S4, we trash it ourselves.
*/
- trash_stolen(i915);
+ trash_stolen(gt);
- intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+ intel_runtime_pm_put(>->i915->runtime_pm, wakeref);
}
static int igt_pm_prepare(struct drm_i915_private *i915)
@@ -99,29 +100,29 @@ static int igt_pm_prepare(struct drm_i915_private *i915)
return 0;
}
-static void igt_pm_suspend(struct drm_i915_private *i915)
+static void igt_pm_suspend(struct intel_gt *gt)
{
intel_wakeref_t wakeref;
- with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
- i915_ggtt_suspend(to_gt(i915)->ggtt);
- i915_gem_suspend_late(i915);
+ with_intel_runtime_pm(>->i915->runtime_pm, wakeref) {
+ i915_ggtt_suspend(gt->ggtt);
+ i915_gem_suspend_late(gt->i915);
}
}
-static void igt_pm_hibernate(struct drm_i915_private *i915)
+static void igt_pm_hibernate(struct intel_gt *gt)
{
intel_wakeref_t wakeref;
- with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
- i915_ggtt_suspend(to_gt(i915)->ggtt);
+ with_intel_runtime_pm(>->i915->runtime_pm, wakeref) {
+ i915_ggtt_suspend(gt->ggtt);
- i915_gem_freeze(i915);
- i915_gem_freeze_late(i915);
+ i915_gem_freeze(gt->i915);
+ i915_gem_freeze_late(gt->i915);
}
}
-static void igt_pm_resume(struct drm_i915_private *i915)
+static void igt_pm_resume(struct intel_gt *gt)
{
intel_wakeref_t wakeref;
@@ -129,17 +130,18 @@ static void igt_pm_resume(struct drm_i915_private *i915)
* Both suspend and hibernate follow the same wakeup path and assume
* that runtime-pm just works.
*/
- with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
- i915_ggtt_resume(to_gt(i915)->ggtt);
- if (GRAPHICS_VER(i915) >= 8)
- setup_private_pat(to_gt(i915));
- i915_gem_resume(i915);
+ with_intel_runtime_pm(>->i915->runtime_pm, wakeref) {
+ i915_ggtt_resume(gt->ggtt);
+ if (GRAPHICS_VER(gt->i915) >= 8)
+ setup_private_pat(gt);
+ i915_gem_resume(gt->i915);
}
}
static int igt_gem_suspend(void *arg)
{
- struct drm_i915_private *i915 = arg;
+ struct intel_gt *gt = arg;
+ struct drm_i915_private *i915 = gt->i915;
struct i915_gem_context *ctx;
struct file *file;
int err;
@@ -159,12 +161,12 @@ static int igt_gem_suspend(void *arg)
if (err)
goto out;
- igt_pm_suspend(i915);
+ igt_pm_suspend(gt);
/* Here be dragons! Note that with S3RST any S3 may become S4! */
- simulate_hibernate(i915);
+ simulate_hibernate(gt);
- igt_pm_resume(i915);
+ igt_pm_resume(gt);
err = switch_to_context(ctx);
out:
@@ -174,7 +176,8 @@ static int igt_gem_suspend(void *arg)
static int igt_gem_hibernate(void *arg)
{
- struct drm_i915_private *i915 = arg;
+ struct intel_gt *gt = arg;
+ struct drm_i915_private *i915 = gt->i915;
struct i915_gem_context *ctx;
struct file *file;
int err;
@@ -194,12 +197,12 @@ static int igt_gem_hibernate(void *arg)
if (err)
goto out;
- igt_pm_hibernate(i915);
+ igt_pm_hibernate(gt);
/* Here be dragons! */
- simulate_hibernate(i915);
+ simulate_hibernate(gt);
- igt_pm_resume(i915);
+ igt_pm_resume(gt);
err = switch_to_context(ctx);
out:
@@ -209,7 +212,8 @@ static int igt_gem_hibernate(void *arg)
static int igt_gem_ww_ctx(void *arg)
{
- struct drm_i915_private *i915 = arg;
+ struct intel_gt *gt = arg;
+ struct drm_i915_private *i915 = gt->i915;
struct drm_i915_gem_object *obj, *obj2;
struct i915_gem_ww_ctx ww;
int err = 0;
@@ -254,9 +258,18 @@ int i915_gem_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_gem_hibernate),
SUBTEST(igt_gem_ww_ctx),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
+
+ for_each_gt(gt, i915, id) {
+ if (intel_gt_is_wedged(gt))
+ return 0;
- if (intel_gt_is_wedged(to_gt(i915)))
- return 0;
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
- return i915_live_subtests(tests, i915);
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index fc068dab27f4..3231025a7b7f 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -957,7 +957,8 @@ int i915_vma_mock_selftests(void)
static int igt_vma_remapped_gtt(void *arg)
{
- struct drm_i915_private *i915 = arg;
+ struct intel_gt *gt = arg;
+ struct drm_i915_private *i915 = gt->i915;
const struct intel_remapped_plane_info planes[] = {
{ .width = 1, .height = 1, .src_stride = 1 },
{ .width = 2, .height = 2, .src_stride = 2 },
@@ -990,7 +991,7 @@ static int igt_vma_remapped_gtt(void *arg)
intel_wakeref_t wakeref;
int err = 0;
- if (!i915_ggtt_has_aperture(to_gt(i915)->ggtt))
+ if (!i915_ggtt_has_aperture(gt->ggtt))
return 0;
obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE);
@@ -1107,6 +1108,15 @@ int i915_vma_live_selftests(struct drm_i915_private *i915)
static const struct i915_subtest tests[] = {
SUBTEST(igt_vma_remapped_gtt),
};
+ struct intel_gt *gt;
+ unsigned int id;
+ int err;
+
+ for_each_gt(gt, i915, id) {
+ err = intel_gt_live_subtests(tests, gt);
+ if (err)
+ return err;
+ }
- return i915_live_subtests(tests, i915);
+ return 0;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [RFC 5/5] drm/i915/selftests: Port selftests that access ggtt to work with multi-gt
2026-10-29 1:41 ` [RFC 5/5] drm/i915/selftests: Port selftests that access ggtt to work with multi-gt Krzysztof Niemiec
@ 2026-10-29 1:51 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-10-29 1:51 UTC (permalink / raw)
To: Krzysztof Niemiec, dri-devel, intel-gfx
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] drm/i915/selftests: partial per-GT resume in igt_pm_resume()
- [Medium] drm/i915/selftests: wrong GGTT pinned in igt_vma_remapped_gtt()
--
commit 8db2f33415f217cdf07f8583781cb2c2c4d93d25
Author: Krzysztof Niemiec <krzysztof.niemiec@intel.com>
drm/i915/selftests: Port selftests that access ggtt to work with multi-gt
This patch updates several i915 live selftests in i915_gem_client_blt.c,
i915_gem.c, and i915_vma.c to iterate over each GT via for_each_gt() and
intel_gt_live_subtests() instead of referencing to_gt(i915)->ggtt directly.
> diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c b/drivers/gpu/drm/i915/selftests/i915_gem.c
> index ad650f67114a6..8f72fd1af8d61 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_gem.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_gem.c
[ ... ]
> @@ -99,29 +100,29 @@ static int igt_pm_prepare(struct drm_i915_private *i915)
> return 0;
> }
>
> -static void igt_pm_suspend(struct drm_i915_private *i915)
> +static void igt_pm_suspend(struct intel_gt *gt)
> {
> intel_wakeref_t wakeref;
>
> - with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
> - i915_ggtt_suspend(to_gt(i915)->ggtt);
> - i915_gem_suspend_late(i915);
> + with_intel_runtime_pm(>->i915->runtime_pm, wakeref) {
> + i915_ggtt_suspend(gt->ggtt);
> + i915_gem_suspend_late(gt->i915);
> }
> }
>
> -static void igt_pm_hibernate(struct drm_i915_private *i915)
> +static void igt_pm_hibernate(struct intel_gt *gt)
> {
> intel_wakeref_t wakeref;
>
> - with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
> - i915_ggtt_suspend(to_gt(i915)->ggtt);
> + with_intel_runtime_pm(>->i915->runtime_pm, wakeref) {
> + i915_ggtt_suspend(gt->ggtt);
>
> - i915_gem_freeze(i915);
> - i915_gem_freeze_late(i915);
> + i915_gem_freeze(gt->i915);
> + i915_gem_freeze_late(gt->i915);
> }
> }
>
> -static void igt_pm_resume(struct drm_i915_private *i915)
> +static void igt_pm_resume(struct intel_gt *gt)
> {
> intel_wakeref_t wakeref;
>
> @@ -129,17 +130,18 @@ static void igt_pm_resume(struct drm_i915_private *i915)
> * Both suspend and hibernate follow the same wakeup path and assume
> * that runtime-pm just works.
> */
> - with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
> - i915_ggtt_resume(to_gt(i915)->ggtt);
> - if (GRAPHICS_VER(i915) >= 8)
> - setup_private_pat(to_gt(i915));
> - i915_gem_resume(i915);
> + with_intel_runtime_pm(>->i915->runtime_pm, wakeref) {
> + i915_ggtt_resume(gt->ggtt);
> + if (GRAPHICS_VER(gt->i915) >= 8)
> + setup_private_pat(gt);
> + i915_gem_resume(gt->i915);
> }
> }
[Severity: Medium]
Does converting igt_gem_suspend() and igt_gem_hibernate() into per-GT
subtests via intel_gt_live_subtests() leave non-target GTs with
unconfigured private PAT registers and unresumed GGTT mappings while
device-wide GEM suspend and resume still reset and submit work to all GTs?
In igt_gem_suspend() and igt_gem_hibernate(), live_context(i915, file)
creates a context with engines across all GTs, and switch_to_context(ctx)
submits requests across every engine on all GTs.
Similarly, the GEM suspend/resume helpers operate across all GTs on the
device:
igt_pm_prepare()
-> i915_gem_suspend()
-> for_each_gt() intel_gt_suspend_prepare(gt)
igt_pm_suspend()
-> i915_gem_suspend_late()
-> for_each_gt() intel_gt_suspend_late(gt)
igt_pm_resume()
-> i915_gem_resume()
-> for_each_gt() intel_gt_resume(gt)
However, igt_pm_suspend(), igt_pm_hibernate(), and igt_pm_resume() only
call i915_ggtt_suspend(gt->ggtt), i915_ggtt_resume(gt->ggtt), and
setup_private_pat(gt) on the single gt passed to the subtest. By contrast,
i915_drm_resume() in drivers/gpu/drm/i915/i915_driver.c programs the
private PAT for every GT before calling i915_gem_resume():
for_each_gt(gt, dev_priv, i)
if (GRAPHICS_VER(gt->i915) >= 8)
setup_private_pat(gt);
On multi-GT platforms, sanitizing and resetting all GTs while only calling
setup_private_pat(gt) and i915_ggtt_resume(gt->ggtt) on one GT leaves the
other GTs without private PAT setup (and without GGTT/GuC mapping resume if
the GTs have separate GGTTs) when i915_gem_resume() and
switch_to_context(ctx) execute across all GTs.
In addition, running i915_gem_live_selftests() in a for_each_gt() loop via
intel_gt_live_subtests() only waits for idle on a single GT in
__intel_gt_live_setup() and redundantly runs the GT-independent
igt_gem_ww_ctx() test once per GT. Should i915_gem_live_selftests() remain
a device-level i915_live_subtests() run and iterate for_each_gt() inside
igt_pm_suspend(), igt_pm_hibernate(), igt_pm_resume(), and trash_stolen()
instead?
> diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
> index fc068dab27f44..3231025a7b7fa 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_vma.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
> @@ -957,7 +957,8 @@ int i915_vma_mock_selftests(void)
>
> static int igt_vma_remapped_gtt(void *arg)
> {
> - struct drm_i915_private *i915 = arg;
> + struct intel_gt *gt = arg;
> + struct drm_i915_private *i915 = gt->i915;
> const struct intel_remapped_plane_info planes[] = {
> { .width = 1, .height = 1, .src_stride = 1 },
> { .width = 2, .height = 2, .src_stride = 2 },
> @@ -990,7 +991,7 @@ static int igt_vma_remapped_gtt(void *arg)
> intel_wakeref_t wakeref;
> int err = 0;
>
> - if (!i915_ggtt_has_aperture(to_gt(i915)->ggtt))
> + if (!i915_ggtt_has_aperture(gt->ggtt))
> return 0;
>
> obj = i915_gem_object_create_internal(i915, 10 * 10 * PAGE_SIZE);
[Severity: Medium]
In igt_vma_remapped_gtt(), the aperture check is updated to inspect
gt->ggtt, but doesn't the body of the loop still pin into
to_gt(i915)->ggtt?
Later in igt_vma_remapped_gtt(), the object is pinned twice using
i915_gem_object_ggtt_pin():
vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
...
vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
i915_gem_object_ggtt_pin() calls i915_gem_object_ggtt_pin_ww() with
ggtt = NULL, which defaults to to_gt(i915)->ggtt:
drivers/gpu/drm/i915/i915_gem.c:i915_gem_object_ggtt_pin_ww() {
struct drm_i915_private *i915 = to_i915(obj->base.dev);
struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
if (_ggtt)
ggtt = _ggtt;
...
}
If a non-primary GT has its own GGTT, igt_vma_remapped_gtt() will still
bind and map through to_gt(i915)->ggtt (or fail with -E2BIG if
to_gt(i915)->ggtt has a smaller aperture than gt->ggtt). Should those two
calls use i915_gem_object_ggtt_pin_ww(obj, NULL, gt->ggtt, ...) so that
gt->ggtt is actually used?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261029014155.55865-1-krzysztof.niemiec@intel.com?part=5
^ permalink raw reply [flat|nested] 10+ messages in thread
* ✗ i915.CI.BAT: failure for Selftests fixes for multi-gt platforms in i915
2026-10-29 1:41 [RFC 0/5] Selftests fixes for multi-gt platforms in i915 Krzysztof Niemiec
` (4 preceding siblings ...)
2026-10-29 1:41 ` [RFC 5/5] drm/i915/selftests: Port selftests that access ggtt to work with multi-gt Krzysztof Niemiec
@ 2026-10-29 2:40 ` Patchwork
5 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2026-10-29 2:40 UTC (permalink / raw)
To: Krzysztof Niemiec; +Cc: intel-gfx
[-- Attachment #1: Type: text/plain, Size: 7880 bytes --]
== Series Details ==
Series: Selftests fixes for multi-gt platforms in i915
URL : https://patchwork.freedesktop.org/series/177065/
State : failure
== Summary ==
CI Bug Log - changes from CI_DRM_19410 -> Patchwork_177065v1
====================================================
Summary
-------
**FAILURE**
Serious unknown changes coming with Patchwork_177065v1 absolutely need to be
verified manually.
If you think the reported changes have nothing to do with the changes
introduced in Patchwork_177065v1, please notify your bug team (I915-ci-infra@lists.freedesktop.org) to allow them
to document this new failure mode, which will reduce false positives in CI.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_177065v1/index.html
Participating hosts (40 -> 38)
------------------------------
Missing (2): bat-dg2-13 bat-arlh-3
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in Patchwork_177065v1:
### IGT changes ###
#### Possible regressions ####
* igt@i915_selftest@live:
- bat-mtlp-8: [PASS][1] -> [ABORT][2] +1 other test abort
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19410/bat-mtlp-8/igt@i915_selftest@live.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_177065v1/bat-mtlp-8/igt@i915_selftest@live.html
* igt@i915_selftest@live@workarounds:
- bat-arls-5: [PASS][3] -> [INCOMPLETE][4] +1 other test incomplete
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19410/bat-arls-5/igt@i915_selftest@live@workarounds.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_177065v1/bat-arls-5/igt@i915_selftest@live@workarounds.html
- bat-arlh-2: [PASS][5] -> [INCOMPLETE][6]
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19410/bat-arlh-2/igt@i915_selftest@live@workarounds.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_177065v1/bat-arlh-2/igt@i915_selftest@live@workarounds.html
- bat-arls-6: [PASS][7] -> [ABORT][8] +1 other test abort
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19410/bat-arls-6/igt@i915_selftest@live@workarounds.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_177065v1/bat-arls-6/igt@i915_selftest@live@workarounds.html
New tests
---------
New tests have been introduced between CI_DRM_19410 and Patchwork_177065v1:
### New IGT tests (46) ###
* igt@i915_selftest@addfb25-4-tiled:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@addfb25-bad-modifier:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@addfb25-modifier-no-flag:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@addfb25-y-tiled-legacy:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@addfb25-yf-tiled-legacy:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@bad-flink:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@bad-pitch-0:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@bad-pitch-32:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@bad-pitch-63:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@bad-pitch-65536:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@bad-pitch-999:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-busy-flip-before-cursor-atomic:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-busy-flip-before-cursor-legacy:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-flip-after-cursor-atomic:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-flip-before-cursor-atomic:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-flip-before-cursor-legacy:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-flip-before-cursor-varying-size:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-flip-vs-dpms:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-pci-d3-state:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-plain-flip:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-with_fd_dup:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-x-tiled-legacy:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@basic-y-tiled-legacy:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@bo-too-small:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@bo-too-small-due-to-tiling:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@compare-crc-sanitycheck-nv12:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@compare-crc-sanitycheck-xr24:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@double-flink:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@engines:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@force-connector-state:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@force-edid:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@force-load-detect:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@framebuffer-vs-set-tiling:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@hang-read-crc:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@invalid-get-prop-any:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@nonblocking-crc:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@prune-stale-modes:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@psr-cursor-plane-move:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@psr-primary-mmap-gtt:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@psr-primary-page-flip:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@psr-sprite-plane-onoff:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@read-crc:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@read-crc-frame-sequence:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@size-max:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@small-bo:
- Statuses :
- Exec time: [None] s
* igt@i915_selftest@tile-pitch-mismatch:
- Statuses :
- Exec time: [None] s
Known issues
------------
Here are the changes found in Patchwork_177065v1 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@i915_selftest@live:
- bat-arlh-2: [PASS][9] -> [INCOMPLETE][10] ([i915#16547])
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19410/bat-arlh-2/igt@i915_selftest@live.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_177065v1/bat-arlh-2/igt@i915_selftest@live.html
* igt@i915_selftest@live@workarounds:
- bat-mtlp-9: [PASS][11] -> [INCOMPLETE][12] ([i915#16229]) +1 other test incomplete
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_19410/bat-mtlp-9/igt@i915_selftest@live@workarounds.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_177065v1/bat-mtlp-9/igt@i915_selftest@live@workarounds.html
[i915#16229]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/16229
[i915#16547]: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/16547
Build changes
-------------
* Linux: CI_DRM_19410 -> Patchwork_177065v1
CI-20190529: 20190529
CI_DRM_19410: 114156ff58b8db80a36355fd6a28725dc7e20584 @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_9170: 9170
Patchwork_177065v1: 114156ff58b8db80a36355fd6a28725dc7e20584 @ git://anongit.freedesktop.org/gfx-ci/linux
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_177065v1/index.html
[-- Attachment #2: Type: text/html, Size: 9983 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread