Allow the caller to specify a dword, or an arbitrary payload, to be written by the busy spinner, just prior to starting its infinite loop. This is similar to the dependency method, that makes a target busy without writing anything. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- lib/igt_dummyload.c | 71 +++++++++++++++++++++++++++++++++++-- lib/igt_dummyload.h | 12 +++++++ tests/i915/gem_spin_batch.c | 46 ++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 2 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 28fcbf81f..d5a68a46c 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -63,7 +63,7 @@ #define MI_ARB_CHK (0x5 << 23) static const int BATCH_SIZE = 4096; -static const int LOOP_START_OFFSET = 64; +static const int LOOP_START_OFFSET = 256; static IGT_LIST_HEAD(spin_list); static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER; @@ -132,6 +132,11 @@ emit_recursive_batch(igt_spin_t *spin, !gem_class_can_store_dword(fd, engine->class)) continue; + if (opts->flags & (IGT_SPIN_STORE_DWORD | + IGT_SPIN_STORE_DATA) && + !gem_class_can_store_dword(fd, engine->class)) + continue; + flags[nengine++] = engine->flags; } } else { @@ -160,6 +165,8 @@ emit_recursive_batch(igt_spin_t *spin, if (opts->dependency) { igt_assert(!(opts->flags & IGT_SPIN_POLL_RUN)); + igt_assert(!(opts->flags & (IGT_SPIN_STORE_DWORD | + IGT_SPIN_STORE_DATA))); obj[SCRATCH].handle = opts->dependency; obj[SCRATCH].offset = addr; @@ -178,6 +185,9 @@ emit_recursive_batch(igt_spin_t *spin, execbuf->buffer_count++; } else if (opts->flags & IGT_SPIN_POLL_RUN) { + igt_assert(!(opts->flags & (IGT_SPIN_STORE_DWORD | + IGT_SPIN_STORE_DATA))); + r = &relocs[obj[BATCH].relocation_count++]; igt_assert(!opts->dependency); @@ -230,6 +240,63 @@ emit_recursive_batch(igt_spin_t *spin, *cs++ = 1; + execbuf->buffer_count++; + } else if (opts->flags & (IGT_SPIN_STORE_DWORD | IGT_SPIN_STORE_DATA)) { + int len, cmd; + + igt_assert(opts->store_handle); + igt_assert((opts->store_offset & 3) == 0); + if (opts->flags & IGT_SPIN_STORE_DATA) { + igt_assert(!(opts->flags & IGT_SPIN_STORE_DWORD)); + igt_assert(opts->store_length < LOOP_START_OFFSET - 16); + igt_assert(opts->store_data); + len = opts->store_length; + } else { + len = sizeof(uint32_t); + } + + addr += 4096; /* guard page */ + obj[SCRATCH].offset = addr; + obj[SCRATCH].handle = opts->store_handle; + obj[SCRATCH].flags = EXEC_OBJECT_WRITE; + + r = &relocs[obj[BATCH].relocation_count++]; + r->read_domains = I915_GEM_DOMAIN_RENDER; + r->write_domain = I915_GEM_DOMAIN_RENDER; + + if (gen == 4 || gen == 5) { + execbuf->flags |= I915_EXEC_SECURE; + igt_require(__igt_device_set_master(fd) == 0); + } + + r->presumed_offset = obj[SCRATCH].offset; + r->target_handle = obj[SCRATCH].handle; + r->offset = sizeof(uint32_t) * 1; + r->delta = opts->store_offset; + + cmd = len / sizeof(uint32_t) + 1; + if (gen >= 4) + cmd++; + *cs++ = 0x20 << 23 | (gen < 6 ? 1 << 22 : 0) | cmd; + + if (gen >= 8) { + *cs++ = r->presumed_offset + r->delta; + *cs++ = 0; + } else if (gen >= 4) { + *cs++ = 0; + *cs++ = r->presumed_offset + r->delta; + r->offset += sizeof(uint32_t); + } else { + *cs++ = r->presumed_offset + r->delta; + } + + if (opts->flags & IGT_SPIN_STORE_DWORD) { + *cs++ = opts->store_dw; + } else { + memcpy(cs, opts->store_data, len); + cs += len / sizeof(*cs); + } + execbuf->buffer_count++; } @@ -258,7 +325,7 @@ emit_recursive_batch(igt_spin_t *spin, * trouble. See https://bugs.freedesktop.org/show_bug.cgi?id=102262 */ if (!(opts->flags & IGT_SPIN_FAST)) - cs += 960; + cs = spin->batch + 1000; /* * When using a cmdparser, the batch is copied into a read only location diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index 9e19ffabc..bc8e8ebb3 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -62,6 +62,16 @@ struct igt_spin_factory { unsigned int engine; unsigned int flags; int fence; + + uint32_t store_handle; + uint32_t store_offset; + union { + struct { + void *store_data; + uint32_t store_length; + }; + uint32_t store_dw; + }; }; #define IGT_SPIN_FENCE_IN (1 << 0) @@ -73,6 +83,8 @@ struct igt_spin_factory { #define IGT_SPIN_INVALID_CS (1 << 6) #define IGT_SPIN_USERPTR (1 << 7) #define IGT_SPIN_SOFTDEP (1 << 8) +#define IGT_SPIN_STORE_DWORD (1 << 9) +#define IGT_SPIN_STORE_DATA (1 << 10) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts); diff --git a/tests/i915/gem_spin_batch.c b/tests/i915/gem_spin_batch.c index 19bc4638d..1ce865d6d 100644 --- a/tests/i915/gem_spin_batch.c +++ b/tests/i915/gem_spin_batch.c @@ -71,6 +71,45 @@ static void spin(int fd, assert_within_epsilon(timeout_100ms * loops, elapsed, MAX_ERROR); } +static void store(int fd, const struct intel_execution_engine2 *e2) +{ + igt_spin_t *spin; + uint32_t handle; + uint32_t *map; + int i; + + handle = gem_create(fd, 4096); + map = gem_mmap__device_coherent(fd, handle, 0, 4096, PROT_WRITE); + + spin = igt_spin_new(fd, + .engine = e2->flags, + .store_handle = handle, + .store_dw = 0xdeadbeef, + .flags = IGT_SPIN_STORE_DWORD); + igt_spin_end(spin); + gem_sync(fd, spin->handle); + igt_spin_free(fd, spin); + igt_assert_eq(map[0], 0xdeadbeef); + + for (i = 0; i < 16; i++) + map[i] = i; + spin = igt_spin_new(fd, + .engine = e2->flags, + .store_handle = handle, + .store_offset = sizeof(uint32_t), + .store_length = 16 * sizeof(uint32_t), + .store_data = map, + .flags = IGT_SPIN_STORE_DATA); + igt_spin_end(spin); + gem_sync(fd, spin->handle); + igt_spin_free(fd, spin); + for (i = 0; i < 16; i++) + igt_assert_eq(map[i + 1], i); + + munmap(map, 4096); + gem_close(fd, handle); +} + #define RESUBMIT_NEW_CTX (1 << 0) #define RESUBMIT_ALL_ENGINES (1 << 1) @@ -204,6 +243,13 @@ igt_main igt_subtest("spin-all-new") spin_all(fd, PARALLEL_SPIN_NEW_CTX); + igt_subtest_with_dynamic("store"){ + __for_each_physical_engine(fd, e2) { + igt_dynamic_f("%s", e2->name) + store(fd, e2); + } + } + __for_each_physical_engine(fd, e2) { igt_subtest_f("%s", e2->name) spin(fd, e2, 0, 3); -- 2.29.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx