diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2020-04-30 22:14:35 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2020-04-30 22:45:22 +0100 |
commit | 57ee41f12b7a53283fd812c5f72fcb39e6ad2197 (patch) | |
tree | 52651069f5a202bf25f5c9b2fada26b996bc96d7 /tests/i915/gem_exec_reloc.c | |
parent | 94de923ca8d4cc8f532b8062d87aaad9da6ef956 (diff) |
i915/gem_exec_reloc: Flood the ring with GPU relocs
Try to fill the ring with GPU relocations and cause the execution to
block; only to be resolved by a GPU hang.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Diffstat (limited to 'tests/i915/gem_exec_reloc.c')
-rw-r--r-- | tests/i915/gem_exec_reloc.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/tests/i915/gem_exec_reloc.c b/tests/i915/gem_exec_reloc.c index 4112e145..5f2f029d 100644 --- a/tests/i915/gem_exec_reloc.c +++ b/tests/i915/gem_exec_reloc.c @@ -26,6 +26,7 @@ #include "igt.h" #include "igt_dummyload.h" +#include "sw_sync.h" IGT_TEST_DESCRIPTION("Basic sanity check of execbuf-ioctl relocations."); @@ -330,6 +331,81 @@ static void active(int fd, unsigned engine) gem_close(fd, obj[0].handle); } +static uint64_t many_relocs(unsigned long count, unsigned long *out) +{ + struct drm_i915_gem_relocation_entry *reloc; + unsigned long sz; + int i; + + sz = count * sizeof(*reloc); + sz = ALIGN(sz, 4096); + + reloc = mmap(0, sz, PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + igt_assert(reloc != MAP_FAILED); + for (i = 0; i < count; i++) { + reloc[i].target_handle = 0; + reloc[i].presumed_offset = ~0ull; + reloc[i].offset = 8 * i; + reloc[i].delta = 8 * i; + } + mprotect(reloc, sz, PROT_READ); + + *out = sz; + return to_user_pointer(reloc); +} + +static void __many_active(int i915, unsigned engine, unsigned long count) +{ + unsigned long reloc_sz; + struct drm_i915_gem_exec_object2 obj[2] = {{ + .handle = gem_create(i915, count * sizeof(uint64_t)), + .relocs_ptr = many_relocs(count, &reloc_sz), + .relocation_count = count, + }}; + struct drm_i915_gem_execbuffer2 execbuf = { + .buffers_ptr = to_user_pointer(obj), + .buffer_count = ARRAY_SIZE(obj), + .flags = engine | I915_EXEC_HANDLE_LUT, + }; + igt_spin_t *spin; + + spin = __igt_spin_new(i915, + .engine = engine, + .dependency = obj[0].handle, + .flags = (IGT_SPIN_FENCE_OUT | + IGT_SPIN_NO_PREEMPTION)); + obj[1] = spin->obj[1]; + gem_execbuf(i915, &execbuf); + igt_assert_eq(sync_fence_status(spin->out_fence), 0); + igt_spin_free(i915, spin); + + for (unsigned long i = 0; i < obj[0].relocation_count; i++) { + uint64_t addr; + + gem_read(i915, obj[0].handle, i * sizeof(addr), + &addr, sizeof(addr)); + + igt_assert_eq_u64(addr, obj[0].offset + i * sizeof(addr)); + } + + munmap(from_user_pointer(obj[0].relocs_ptr), reloc_sz); + gem_close(i915, obj[0].handle); +} + +static void many_active(int i915, unsigned engine) +{ + unsigned long count = 256; + + igt_until_timeout(5) { + igt_debug("Testing count:%lu\n", count); + __many_active(i915, engine, count); + + count <<= 2; + if (!count) + break; + } +} + static unsigned int offset_in_page(void *addr) { return (uintptr_t)addr & 4095; @@ -981,6 +1057,13 @@ igt_main } } + igt_subtest_with_dynamic("basic-many-active") { + __for_each_physical_engine(fd, e) { + igt_dynamic_f("%s", e->name) + many_active(fd, e->flags); + } + } + igt_subtest("basic-parallel") parallel(fd); |