[PATCH i-g-t] i915/perf_pmu: Verify that waiters do not report as busy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If we queue requests that must wait for the current spinner to finish,
those waiting engines should not be reported as busy (or else we perturb
scheduling logic that tries to distribute workloads onto idle engines --
if all engines are busy, even those waiting, it degrades into a
round-robin free-for-all).

Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx>
---
 tests/i915/perf_pmu.c | 64 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/tests/i915/perf_pmu.c b/tests/i915/perf_pmu.c
index 755e1b9ee..aa2583205 100644
--- a/tests/i915/perf_pmu.c
+++ b/tests/i915/perf_pmu.c
@@ -541,6 +541,67 @@ most_busy_check_all(int gem_fd, const struct intel_execution_engine2 *e,
 	gem_quiescent_gpu(gem_fd);
 }
 
+static void
+busy_wait_check_all(int gem_fd,
+		    const struct intel_execution_engine2 *e,
+		    const unsigned int num_engines)
+{
+	const struct intel_execution_engine2 *e_;
+	uint64_t tval[2][num_engines];
+	uint64_t val[num_engines];
+	int fd[num_engines];
+	unsigned long slept;
+	igt_spin_t *spin;
+	unsigned int busy_idx, i;
+
+	/*
+	 * One engine busy spins, all others waiting for the spinner, with
+	 * the expected result that only active spinner is reported as busy.
+	 */
+
+	spin = __spin_poll(gem_fd, 0, e2ring(gem_fd, e));
+	spin->obj[0].flags |= EXEC_OBJECT_WRITE;
+
+	i = 0;
+	for_each_engine_class_instance(gem_fd, e_) {
+		if (e == e_)
+			busy_idx = i;
+		else
+			__submit_spin_batch(gem_fd, spin, e_, 64);
+
+		val[i++] = I915_PMU_ENGINE_BUSY(e_->class, e_->instance);
+	}
+	igt_assert(i == num_engines);
+
+	fd[0] = -1;
+	for (i = 0; i < num_engines; i++)
+		fd[i] = open_group(val[i], fd[0]);
+
+	/* Small delay to allow engines to start. */
+	usleep(__spin_wait(gem_fd, spin) * num_engines / 1e3);
+
+	pmu_read_multi(fd[0], num_engines, tval[0]);
+	slept = measured_usleep(batch_duration_ns / 1000);
+	pmu_read_multi(fd[0], num_engines, tval[1]);
+
+	end_spin(gem_fd, spin, FLAG_SYNC);
+	igt_spin_batch_free(gem_fd, spin);
+	close(fd[0]);
+
+	for (i = 0; i < num_engines; i++)
+		val[i] = tval[1][i] - tval[0][i];
+
+	log_busy(num_engines, val);
+
+	for (i = 0; i < num_engines; i++) {
+		if (i == busy_idx)
+			assert_within_epsilon(val[i], slept, tolerance);
+		else
+			assert_within_epsilon(val[i], 0.0f, tolerance);
+	}
+	gem_quiescent_gpu(gem_fd);
+}
+
 static void
 all_busy_check_all(int gem_fd, const unsigned int num_engines,
 		   unsigned int flags)
@@ -1742,6 +1803,9 @@ igt_main
 				busy_check_all(fd, e, num_engines,
 					       TEST_BUSY | TEST_TRAILING_IDLE);
 
+			igt_subtest_f("busy-wait-check-all-%s", e->name)
+				busy_wait_check_all(fd, e, num_engines);
+
 			/**
 			 * Test that when all except one engine are loaded all
 			 * loads are correctly reported.
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux