summaryrefslogtreecommitdiff
path: root/tests/i915/gem_exec_reloc.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2020-04-30 22:14:35 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2020-04-30 22:45:22 +0100
commit57ee41f12b7a53283fd812c5f72fcb39e6ad2197 (patch)
tree52651069f5a202bf25f5c9b2fada26b996bc96d7 /tests/i915/gem_exec_reloc.c
parent94de923ca8d4cc8f532b8062d87aaad9da6ef956 (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.c83
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);