[Intel-gfx] [PATCH igt 2/2] igt/gem_exec_nop: Measure high-priority throughput over a bg load

Chris Wilson chris at chris-wilson.co.uk
Thu Sep 28 17:26:20 UTC 2017


Measure how many high priority batches we can execute whilst running a
bg spinner.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 tests/gem_exec_nop.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/tests/gem_exec_nop.c b/tests/gem_exec_nop.c
index 03335a6d..b582285a 100644
--- a/tests/gem_exec_nop.c
+++ b/tests/gem_exec_nop.c
@@ -45,6 +45,8 @@
 #include <time.h>
 #include "drm.h"
 
+#define BIT(x) (1ul << (x))
+
 #define LOCAL_I915_EXEC_NO_RELOC (1<<11)
 #define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
 
@@ -53,6 +55,14 @@
 
 #define ENGINE_FLAGS  (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
 
+#define LOCAL_PARAM_HAS_SCHEDULER 41
+#define   HAS_SCHEDULER		BIT(0)
+#define   HAS_PRIORITY		BIT(1)
+#define   HAS_PREEMPTION	BIT(2)
+#define LOCAL_CONTEXT_PARAM_PRIORITY 6
+#define   MAX_PRIO 1023
+#define   MIN_PRIO -1023
+
 #define FORKED 1
 #define CHAINED 2
 #define CONTEXT 4
@@ -582,6 +592,79 @@ static void fence_signal(int fd, uint32_t handle,
 	igt_info("Signal %s: %'lu cycles (%'lu signals): %.3fus\n",
 		 ring_name, count, signal, elapsed(&start, &now) * 1e6 / count);
 }
+static int __ctx_set_priority(int fd, uint32_t ctx, int prio)
+{
+	struct local_i915_gem_context_param param;
+
+	memset(&param, 0, sizeof(param));
+	param.context = ctx;
+	param.size = 0;
+	param.param = LOCAL_CONTEXT_PARAM_PRIORITY;
+	param.value = prio;
+
+	return __gem_context_set_param(fd, &param);
+}
+
+static void ctx_set_priority(int fd, uint32_t ctx, int prio)
+{
+	igt_assert_eq(__ctx_set_priority(fd, ctx, prio), 0);
+}
+
+static void preempt(int fd, uint32_t handle,
+		   unsigned ring_id, const char *ring_name)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj;
+	struct timespec start, now;
+	unsigned long count;
+	uint32_t ctx[2];
+
+	gem_require_ring(fd, ring_id);
+
+	ctx[0] = gem_context_create(fd);
+	ctx_set_priority(fd, ctx[0], MIN_PRIO);
+
+	ctx[1] = gem_context_create(fd);
+	ctx_set_priority(fd, ctx[1], MAX_PRIO);
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = handle;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = ring_id;
+	execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
+	execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
+	if (__gem_execbuf(fd, &execbuf)) {
+		execbuf.flags = ring_id;
+		gem_execbuf(fd, &execbuf);
+	}
+	execbuf.rsvd1 = ctx[1];
+	intel_detect_and_clear_missed_interrupts(fd);
+
+	count = 0;
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	do {
+		igt_spin_t *spin =
+			__igt_spin_batch_new(fd, ctx[0], ring_id, 0);
+
+		for (int loop = 0; loop < 1024; loop++)
+			gem_execbuf(fd, &execbuf);
+
+		igt_spin_batch_free(fd, spin);
+
+		count += 1024;
+		clock_gettime(CLOCK_MONOTONIC, &now);
+	} while (elapsed(&start, &now) < 20);
+	igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0);
+
+	gem_context_destroy(fd, ctx[1]);
+	gem_context_destroy(fd, ctx[0]);
+
+	igt_info("%s: %'lu cycles: %.3fus\n",
+		 ring_name, count, elapsed(&start, &now)*1e6 / count);
+}
 
 static void print_welcome(int fd)
 {
@@ -612,9 +695,31 @@ out:
 	close(dir);
 }
 
+static unsigned int has_scheduler(int fd)
+{
+	drm_i915_getparam_t gp;
+	unsigned int caps = 0;
+
+	gp.param = LOCAL_PARAM_HAS_SCHEDULER;
+	gp.value = (int *)∩︀
+	drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
+
+	if (!caps)
+		return 0;
+
+	igt_info("Has kernel scheduler\n");
+	if (caps & HAS_PRIORITY)
+		igt_info(" - With priority sorting\n");
+	if (caps & HAS_PREEMPTION)
+		igt_info(" - With preemption enabled\n");
+
+	return caps;
+}
+
 igt_main
 {
 	const struct intel_execution_engine *e;
+	unsigned int sched_caps = 0;
 	uint32_t handle = 0;
 	int device = -1;
 
@@ -624,6 +729,7 @@ igt_main
 		device = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(device);
 		print_welcome(device);
+		sched_caps = has_scheduler(device);
 
 		handle = gem_create(device, 4096);
 		gem_write(device, handle, 0, &bbe, sizeof(bbe));
@@ -668,6 +774,18 @@ igt_main
 	igt_subtest("context-sequential")
 		sequential(device, handle, FORKED | CONTEXT, 150);
 
+	igt_subtest_group {
+		igt_fixture {
+			igt_require(sched_caps & HAS_PRIORITY);
+			igt_require(sched_caps & HAS_PREEMPTION);
+		}
+
+		for (e = intel_execution_engines; e->name; e++) {
+			igt_subtest_f("preempt-%s", e->name)
+				preempt(device, handle, e->exec_id | e->flags, e->name);
+		}
+	}
+
 #if !defined(ANDROID) || ANDROID_HAS_CAIRO
 	igt_subtest("headless") {
 		/* Requires master for changing display modes */
-- 
2.14.2



More information about the Intel-gfx mailing list