summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2020-05-15 21:32:18 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2020-05-19 14:19:31 +0100
commitbf43e3e45a17c16094fb3a47b363ccf1c95c28b9 (patch)
treea4845d399c52c55d8c6bcc421bfb1cd222283ae5 /tests
parent2a677795335f0ed0a2ddb361b1bc0f81c2565f8e (diff)
i915/gem_exec_balancer: Exercise timeslicing around a hog
If a hog steals an engine after we are already using it for a virtual engine, it is preferrable to reschedule the virtual engine on another to run in parallel to (and complete before) the hog. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/i915/gem_exec_balancer.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/tests/i915/gem_exec_balancer.c b/tests/i915/gem_exec_balancer.c
index 2ff93437..573d0954 100644
--- a/tests/i915/gem_exec_balancer.c
+++ b/tests/i915/gem_exec_balancer.c
@@ -1611,6 +1611,76 @@ static void sliced(int i915)
gem_quiescent_gpu(i915);
}
+static void __hog(int i915, uint32_t ctx, unsigned int count)
+{
+ int64_t timeout = 50 * 1000 * 1000; /* 50ms */
+ igt_spin_t *virtual;
+ igt_spin_t *hog;
+
+ virtual = igt_spin_new(i915, ctx, .engine = 0);
+ for (int i = 0; i < count; i++)
+ gem_execbuf(i915, &virtual->execbuf);
+ usleep(50 * 1000); /* 50ms, long enough to spread across all engines */
+
+ gem_context_set_priority(i915, ctx, 1023);
+ hog = __igt_spin_new(i915, ctx,
+ .engine = 1 + (random() % count),
+ .flags = (IGT_SPIN_POLL_RUN |
+ IGT_SPIN_NO_PREEMPTION));
+ gem_context_set_priority(i915, ctx, 0);
+
+ /* No matter which engine we choose, we'll have interrupted someone */
+ igt_spin_busywait_until_started(hog);
+
+ igt_spin_end(virtual);
+ if (gem_wait(i915, virtual->handle, &timeout)) {
+ igt_debugfs_dump(i915, "i915_engine_info");
+ igt_assert_eq(gem_wait(i915, virtual->handle, &timeout), 0);
+ }
+
+ igt_spin_free(i915, hog);
+ igt_spin_free(i915, virtual);
+}
+
+static void hog(int i915)
+{
+ /*
+ * Suppose there we are, happily using an engine, minding our
+ * own business, when all of a sudden a very important process
+ * takes over the engine and refuses to let go. Clearly we have
+ * to vacate that engine and find a new home.
+ */
+
+ igt_require(gem_scheduler_has_preemption(i915));
+ igt_require(gem_scheduler_has_semaphores(i915));
+
+ for (int class = 0; class < 32; class++) {
+ struct i915_engine_class_instance *ci;
+ unsigned int count;
+ uint32_t ctx;
+
+ ci = list_engines(i915, 1u << class, &count);
+ if (!ci)
+ continue;
+
+ if (count < 2) {
+ free(ci);
+ continue;
+ }
+
+ ctx = load_balancer_create(i915, ci, count);
+
+ __hog(i915, ctx, count);
+
+ gem_context_destroy(i915, ctx);
+ igt_waitchildren();
+
+ free(ci);
+ }
+
+ gem_quiescent_gpu(i915);
+}
+
static void nop(int i915)
{
struct drm_i915_gem_exec_object2 batch = {
@@ -2097,6 +2167,9 @@ igt_main
igt_subtest("sliced")
sliced(i915);
+ igt_subtest("hog")
+ hog(i915);
+
igt_subtest("smoke")
smoketest(i915, 20);