[PATCH igt] igt/gem_exec_latency: Wire up an interloper for preemption

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

 



For measuring the cost of preemption, inject a low priority spinner
between the two measurements; the difference between the preemption and
the normal dispatch includes both the cost of the spinner dispatch and
of preempting it. Close enough for us to estimate the cost of
preemption, though we don't measure the cost of preemption on the local
ring!

Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
CC: Michał Winiarski <michal.winiarski@xxxxxxxxx>
---
 tests/gem_exec_latency.c | 88 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 59 insertions(+), 29 deletions(-)

diff --git a/tests/gem_exec_latency.c b/tests/gem_exec_latency.c
index e9d93440..850404b9 100644
--- a/tests/gem_exec_latency.c
+++ b/tests/gem_exec_latency.c
@@ -50,7 +50,8 @@
 
 #define ENGINE_FLAGS  (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
 
-#define CORK 1
+#define CORK 0x1
+#define PREEMPT 0x2
 
 static unsigned int ring_size;
 
@@ -284,13 +285,23 @@ static void latency_from_ring(int fd,
 	struct drm_i915_gem_execbuffer2 execbuf;
 	const unsigned int repeats = ring_size / 2;
 	uint32_t *map, *results;
+	uint32_t ctx[2] = {};
 	int i, j;
 
+	if (flags & PREEMPT) {
+		ctx[0] = gem_context_create(fd);
+		gem_context_set_priority(fd, ctx[0], -1023);
+
+		ctx[1] = gem_context_create(fd);
+		gem_context_set_priority(fd, ctx[1], 1023);
+	}
+
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj[1]);
 	execbuf.buffer_count = 2;
 	execbuf.flags = ring;
 	execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC | LOCAL_I915_EXEC_HANDLE_LUT;
+	execbuf.rsvd1 = ctx[1];
 
 	memset(obj, 0, sizeof(obj));
 	obj[1].handle = gem_create(fd, 4096);
@@ -319,6 +330,7 @@ static void latency_from_ring(int fd,
 	reloc.target_handle = flags & CORK ? 1 : 0;
 
 	for (e = intel_execution_engines; e->name; e++) {
+		igt_spin_t *spin = NULL;
 		struct cork c;
 
 		if (e->exec_id == 0)
@@ -331,6 +343,9 @@ static void latency_from_ring(int fd,
 			       I915_GEM_DOMAIN_GTT,
 			       I915_GEM_DOMAIN_GTT);
 
+		if (flags & PREEMPT)
+			spin = igt_spin_batch_new(fd, ctx[0], ring, 0);
+
 		if (flags & CORK) {
 			plug(fd, &c);
 			obj[0].handle = c.handle;
@@ -349,6 +364,7 @@ static void latency_from_ring(int fd,
 				execbuf.batch_start_offset + sizeof(uint32_t);
 			reloc.delta = sizeof(uint32_t) * j;
 
+			reloc.presumed_offset = obj[1].offset;
 			offset = reloc.presumed_offset;
 			offset += reloc.delta;
 
@@ -373,6 +389,7 @@ static void latency_from_ring(int fd,
 				execbuf.batch_start_offset + sizeof(uint32_t);
 			reloc.delta = sizeof(uint32_t) * (j + repeats);
 
+			reloc.presumed_offset = obj[1].offset;
 			offset = reloc.presumed_offset;
 			offset += reloc.delta;
 
@@ -392,10 +409,10 @@ static void latency_from_ring(int fd,
 
 		if (flags & CORK)
 			unplug(&c);
-
 		gem_set_domain(fd, obj[1].handle,
 			       I915_GEM_DOMAIN_GTT,
 			       I915_GEM_DOMAIN_GTT);
+		igt_spin_batch_free(fd, spin);
 
 		igt_info("%s-%s delay: %.2f\n",
 			 name, e->name, (results[2*repeats-1] - results[0]) / (double)repeats);
@@ -405,6 +422,11 @@ static void latency_from_ring(int fd,
 	munmap(results, 4096);
 	gem_close(fd, obj[1].handle);
 	gem_close(fd, obj[2].handle);
+
+	if (flags & PREEMPT) {
+		gem_context_destroy(fd, ctx[1]);
+		gem_context_destroy(fd, ctx[0]);
+	}
 }
 
 igt_main
@@ -437,37 +459,45 @@ igt_main
 			if (e->exec_id == 0)
 				continue;
 
-			igt_subtest_f("%s-dispatch", e->name) {
-				gem_require_ring(device, e->exec_id | e->flags);
-				latency_on_ring(device,
-						e->exec_id | e->flags,
-						e->name, 0);
-			}
-
-			igt_subtest_f("%s-dispatch-queued", e->name) {
-				gem_require_ring(device, e->exec_id | e->flags);
-				latency_on_ring(device,
-						e->exec_id | e->flags,
-						e->name, CORK);
-			}
-
-			igt_subtest_f("%s-synchronisation", e->name) {
-				gem_require_ring(device, e->exec_id | e->flags);
-				latency_from_ring(device,
-						  e->exec_id | e->flags,
-						  e->name, 0);
-			}
-
-			igt_subtest_f("%s-synchronisation-queued", e->name) {
-				gem_require_ring(device, e->exec_id | e->flags);
-				latency_from_ring(device,
-						  e->exec_id | e->flags,
-						  e->name, CORK);
+			igt_subtest_group {
+				igt_fixture {
+					gem_require_ring(device, e->exec_id | e->flags);
+				}
+
+				igt_subtest_f("%s-dispatch", e->name)
+					latency_on_ring(device,
+							e->exec_id | e->flags,
+							e->name, 0);
+
+				igt_subtest_f("%s-dispatch-queued", e->name)
+					latency_on_ring(device,
+							e->exec_id | e->flags,
+							e->name, CORK);
+
+				igt_subtest_f("%s-synchronisation", e->name)
+					latency_from_ring(device,
+							  e->exec_id | e->flags,
+							  e->name, 0);
+
+				igt_subtest_f("%s-synchronisation-queued", e->name)
+					latency_from_ring(device,
+							  e->exec_id | e->flags,
+							  e->name, CORK);
+
+				igt_subtest_group {
+					igt_fixture {
+						igt_require(gem_scheduler_has_preemption(device));
+					}
+
+					igt_subtest_f("%s-preemption", e->name)
+						latency_from_ring(device,
+								  e->exec_id | e->flags,
+								  e->name, PREEMPT);
+				}
 			}
 		}
 	}
 
-
 	igt_fixture {
 		close(device);
 	}
-- 
2.15.0.rc2

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




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux