[PATCH i-g-t v2 1/2] tests/i915/perf: Exercise barrier race

Janusz Krzysztofik janusz.krzysztofik at linux.intel.com
Thu Feb 2 15:17:18 UTC 2023


Users reported oopses on list corruptions when using i915 perf with a
number of concurrently running graphics applications.  That indicates we
are currently missing some important tests for such scenarios.  Cover
that gap.

Since root cause analysis pointed out to an issue in barrier processing
code, add a new subtest focused on exercising interaction between perf
open / close operations, which replace active barriers with perf requests,
and concurrent barrier preallocate / acquire operations performed during
context first pin / last unpin.

Note: The new subtest would probably better fit into a test that exercises
context pin / unpin in the first place, however, the only known way to
trigger the list corruption bug is via perf open / close.  Since there is
no IGT library providing perf helpers, it was most convenient to implement
the new subtest inside perf test.  As soon as such library is created, the
subtest can be moved to where it belongs.

v2: refactor existing code and avoid adding bool logic into function
    (Kamil),
  - add TODO comment on future moving the new subtest to another test
    (Kamil),
  - drop new GEM context creation, it occurred not needed for triggering
    the bug (execbuf was not using that new context anyway).

References: https://gitlab.freedesktop.org/drm/intel/-/issues/6333
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik at linux.intel.com>
Cc: Chris Wilson <chris.p.wilson at linux.intel.com>
---
 tests/i915/perf.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/tests/i915/perf.c b/tests/i915/perf.c
index dd1f1ac399..2868efcfe7 100644
--- a/tests/i915/perf.c
+++ b/tests/i915/perf.c
@@ -39,6 +39,7 @@
 #include <math.h>
 
 #include "i915/gem.h"
+#include "i915/gem_create.h"
 #include "i915/perf.h"
 #include "igt.h"
 #include "igt_perf.h"
@@ -4885,6 +4886,68 @@ test_whitelisted_registers_userspace_config(void)
 	i915_perf_remove_config(drm_fd, config_id);
 }
 
+static void perf_open_close_loop(int fd, int *done)
+{
+	uint64_t properties[] = {
+		DRM_I915_PERF_PROP_SAMPLE_OA, true,
+		DRM_I915_PERF_PROP_OA_METRICS_SET, test_set->perf_oa_metrics_set,
+		DRM_I915_PERF_PROP_OA_FORMAT, test_set->perf_oa_format,
+		DRM_I915_PERF_PROP_OA_EXPONENT, oa_exp_1_millisec,
+	};
+	struct drm_i915_perf_open_param param = {
+		.flags = I915_PERF_FLAG_FD_CLOEXEC,
+		.num_properties = sizeof(properties) / 16,
+		.properties_ptr = to_user_pointer(properties),
+	};
+	unsigned long count = 0;
+
+	do {
+		__perf_close(__perf_open(fd, &param, false));
+		count++;
+	} while (!READ_ONCE(*done));
+
+	igt_info("Completed %lu cycles\n", count);
+}
+
+static void test_barrier_race(const struct intel_execution_engine2 *e, int timeout)
+{
+	int *done;
+
+	done = mmap(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+	igt_assert(done != MAP_FAILED);
+
+	igt_fork(child, 1)
+		perf_open_close_loop(drm_fd, done);
+
+	igt_fork(child, sysconf(_SC_NPROCESSORS_ONLN)) {
+		int i915 = gem_reopen_driver(drm_fd);
+
+		do {
+			const uint32_t bbe = MI_BATCH_BUFFER_END;
+			struct drm_i915_gem_exec_object2 obj = { };
+			struct drm_i915_gem_execbuffer2 execbuf = {
+				.buffers_ptr = to_user_pointer(&obj),
+				.buffer_count = 1,
+			};
+
+			obj.handle = gem_create(i915, 4096);
+			gem_write(i915, obj.handle, 0, &bbe, sizeof(bbe));
+
+			execbuf.flags = e->flags;
+			gem_execbuf(i915, &execbuf);
+
+			gem_sync(i915, obj.handle);
+			gem_close(i915, obj.handle);
+		} while (!READ_ONCE(*done));
+	}
+
+	sleep(timeout);
+	*done = 1;
+	igt_waitchildren();
+
+	munmap(done, 4096);
+}
+
 static unsigned
 read_i915_module_ref(void)
 {
@@ -5259,6 +5322,23 @@ igt_main
 	igt_subtest("whitelisted-registers-userspace-config")
 		test_whitelisted_registers_userspace_config();
 
+	igt_describe("Exercise perf open/close against intensive barrier preallocate/acquire");
+	/*
+	 * TODO: As soon as IGT perf library is available, move this subtest
+	 *	 to a test focused on exercising context pin/unpin operations
+	 */
+	igt_subtest_with_dynamic("barrier-race") {
+		const struct intel_execution_engine2 *e;
+
+		for_each_physical_engine(drm_fd, e) {
+			if (e->class != I915_ENGINE_CLASS_RENDER)
+				continue;
+
+			igt_dynamic_f("%s", e->name)
+				test_barrier_race(e, 5);
+		}
+	}
+
 	igt_fixture {
 		/* leave sysctl options in their default state... */
 		write_u64_file("/proc/sys/dev/i915/oa_max_sample_rate", 100000);
-- 
2.25.1



More information about the Intel-gfx-trybot mailing list