summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-04-24 16:32:58 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2019-04-25 13:37:14 +0100
commita75429544f5721316b04a36551c57573e0c79486 (patch)
tree4c6ca9e56dcb33012272480c53c85558881cd544
parent7f18fe6bcd2f7a5dcc4f299c2c0b3001c2368263 (diff)
i915/gem_exec_schedule: Check deps along implicit inter-engine semaphores
Given an implicit semaphore from one engine to the next, check that if we skip the wait on that semaphore the following batch although submitted early (as it depends along the single engine timeline) is not executed ahead of its dependency. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
-rw-r--r--tests/i915/gem_exec_schedule.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/tests/i915/gem_exec_schedule.c b/tests/i915/gem_exec_schedule.c
index a55b8452..330e8a54 100644
--- a/tests/i915/gem_exec_schedule.c
+++ b/tests/i915/gem_exec_schedule.c
@@ -603,6 +603,86 @@ static void semaphore_resolve(int i915)
gem_context_destroy(i915, outer);
}
+static void semaphore_noskip(int i915)
+{
+ const int gen = intel_gen(intel_get_drm_devid(i915));
+ unsigned int engine, other;
+ uint32_t ctx;
+
+ igt_require(gen >= 6); /* MI_STORE_DWORD_IMM convenience */
+
+ ctx = gem_context_create(i915);
+
+ for_each_physical_engine(i915, engine) {
+ for_each_physical_engine(i915, other) {
+ struct drm_i915_gem_exec_object2 obj[3];
+ struct drm_i915_gem_execbuffer2 eb;
+ uint32_t handle, *cs, *map;
+ igt_spin_t *chain, *spin;
+
+ if (other == engine || !gem_can_store_dword(i915, other))
+ continue;
+
+ chain = __igt_spin_new(i915, .engine = engine);
+
+ spin = __igt_spin_new(i915, .engine = other);
+ igt_spin_end(spin); /* we just want its address for later */
+ gem_sync(i915, spin->handle);
+ igt_spin_reset(spin);
+
+ handle = gem_create(i915, 4096);
+ cs = map = gem_mmap__cpu(i915, handle, 0, 4096, PROT_WRITE);
+
+ /* Cancel the following spinner */
+ *cs++ = MI_STORE_DWORD_IMM;
+ if (gen >= 8) {
+ *cs++ = spin->obj[1].offset + offset_in_page(spin->condition);
+ *cs++ = 0;
+ } else {
+ *cs++ = 0;
+ *cs++ = spin->obj[1].offset + offset_in_page(spin->condition);
+ }
+ *cs++ = MI_BATCH_BUFFER_END;
+
+ *cs++ = MI_BATCH_BUFFER_END;
+ munmap(map, 4096);
+
+ /* port0: implicit semaphore from engine */
+ memset(obj, 0, sizeof(obj));
+ obj[0] = chain->obj[1];
+ obj[0].flags |= EXEC_OBJECT_WRITE;
+ obj[1] = spin->obj[1];
+ obj[2].handle = handle;
+ memset(&eb, 0, sizeof(eb));
+ eb.buffer_count = 3;
+ eb.buffers_ptr = to_user_pointer(obj);
+ eb.rsvd1 = ctx;
+ eb.flags = other;
+ gem_execbuf(i915, &eb);
+
+ /* port1: dependency chain from port0 */
+ memset(obj, 0, sizeof(obj));
+ obj[0].handle = handle;
+ obj[0].flags = EXEC_OBJECT_WRITE;
+ obj[1] = spin->obj[1];
+ memset(&eb, 0, sizeof(eb));
+ eb.buffer_count = 2;
+ eb.buffers_ptr = to_user_pointer(obj);
+ eb.flags = other;
+ gem_execbuf(i915, &eb);
+
+ igt_spin_set_timeout(chain, NSEC_PER_SEC / 100);
+ gem_sync(i915, spin->handle); /* To hang unless cancel runs! */
+
+ gem_close(i915, handle);
+ igt_spin_free(i915, spin);
+ igt_spin_free(i915, chain);
+ }
+ }
+
+ gem_context_destroy(i915, ctx);
+}
+
static void reorder(int fd, unsigned ring, unsigned flags)
#define EQUAL 1
{
@@ -1592,6 +1672,8 @@ igt_main
semaphore_codependency(fd);
igt_subtest("semaphore-resolve")
semaphore_resolve(fd);
+ igt_subtest("semaphore-noskip")
+ semaphore_noskip(fd);
igt_subtest("smoketest-all")
smoketest(fd, ALL_ENGINES, 30);