diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2020-11-30 11:37:06 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2020-11-30 11:39:06 +0000 |
commit | cf2f41b3d3dfabaf3a4837062f996f3491a350b1 (patch) | |
tree | 0fbf5aec0d3c57b82f2468f99b3172e7a97dfc93 | |
parent | d1688b297ccd5600cb465dd84685591d63a18026 (diff) |
test/i915/gem_exec_reloc: Restore interclient testings
These tests were removed under a blatantly false statement to hide a
regression. Denying that userspace can deadlock other clients, does not
stop the violations. Introducing such deadlocks deliberately is a cause
for concern.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | tests/i915/gem_exec_reloc.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/tests/i915/gem_exec_reloc.c b/tests/i915/gem_exec_reloc.c index 8dcb24a6..cc9b8cd6 100644 --- a/tests/i915/gem_exec_reloc.c +++ b/tests/i915/gem_exec_reloc.c @@ -424,6 +424,76 @@ static void many_active(int i915, unsigned engine) } } +static void __wide_active(int i915, unsigned engine, unsigned long count) +{ + struct drm_i915_gem_relocation_entry *reloc = + calloc(count, sizeof(*reloc)); + struct drm_i915_gem_exec_object2 *obj = + calloc(count + 1, sizeof(*obj)); + struct drm_i915_gem_execbuffer2 execbuf = { + .buffers_ptr = to_user_pointer(obj), + .buffer_count = count + 1, + .flags = engine | I915_EXEC_HANDLE_LUT, + }; + igt_spin_t *spin; + + for (unsigned long i = 0; i < count; i++) { + obj[i].handle = gem_create(i915, 4096); + obj[i].flags = EXEC_OBJECT_WRITE; + obj[i].flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS; + } + + spin = __igt_spin_new(i915, + .engine = engine, + .flags = (IGT_SPIN_FENCE_OUT | + IGT_SPIN_NO_PREEMPTION)); + obj[count] = spin->obj[1]; + gem_execbuf(i915, &execbuf); /* mark all the objects as active */ + + for (unsigned long i = 0; i < count; i++) { + reloc[i].target_handle = i; + reloc[i].presumed_offset = ~0ull; + obj[i].relocs_ptr = to_user_pointer(&reloc[i]); + obj[i].relocation_count = 1; + } + gem_execbuf(i915, &execbuf); /* relocation onto active objects */ + + igt_assert_eq(sync_fence_status(spin->out_fence), 0); + igt_spin_free(i915, spin); + + for (unsigned long i = 0; i < count; i++) { + uint64_t addr; + + gem_read(i915, obj[i].handle, 0, &addr, sizeof(addr)); + igt_assert_eq_u64(addr, obj[i].offset); + + gem_close(i915, obj[i].handle); + } + free(obj); + free(reloc); +} + +static void wide_active(int i915, unsigned engine) +{ + const uint64_t max = gem_aperture_size(i915) / 4096 / 2; + unsigned long count = 256; + + igt_until_timeout(2) { + uint64_t required, total; + + if (!__intel_check_memory(count, 4096, CHECK_RAM, + &required, &total)) + break; + + igt_debug("Testing count:%lu\n", count); + __wide_active(i915, engine, count); + + count <<= 1; + if (count >= max) + break; + } +} + static unsigned int offset_in_page(void *addr) { return (uintptr_t)addr & 4095; @@ -867,6 +937,145 @@ static void basic_softpin(int fd) gem_close(fd, obj[1].handle); } +static struct drm_i915_gem_relocation_entry * +parallel_relocs(int 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 = i; + reloc[i].read_domains = I915_GEM_DOMAIN_INSTRUCTION; + reloc[i].write_domain = 0; + } + mprotect(reloc, sz, PROT_READ); + + *out = sz; + return reloc; +} + +static int __execbuf(int i915, struct drm_i915_gem_execbuffer2 *execbuf) +{ + int err; + + err = 0; + if (ioctl(i915, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf)) { + err = -errno; + igt_assume(err); + } + + errno = 0; + return err; +} + +static int stop; +static void sighandler(int sig) +{ + stop = 1; +} + +static void parallel_child(int i915, + const struct intel_execution_engine2 *engine, + struct drm_i915_gem_relocation_entry *reloc, + uint32_t common) +{ + igt_spin_t *spin = __igt_spin_new(i915, .engine = engine->flags); + struct drm_i915_gem_exec_object2 reloc_target = { + .handle = gem_create(i915, 32 * 1024 * 8), + .relocation_count = 32 * 1024, + .relocs_ptr = to_user_pointer(reloc), + }; + struct drm_i915_gem_exec_object2 obj[3] = { + reloc_target, + { .handle = common }, + spin->obj[1], + }; + struct drm_i915_gem_execbuffer2 execbuf = { + .buffers_ptr = to_user_pointer(obj), + .buffer_count = ARRAY_SIZE(obj), + .flags = engine->flags | I915_EXEC_HANDLE_LUT, + }; + struct sigaction act = { + .sa_handler = sighandler, + }; + unsigned long count = 0; + + sigaction(SIGINT, &act, NULL); + while (!READ_ONCE(stop)) { + int err = __execbuf(i915, &execbuf); + if (err == -EINTR) + break; + + igt_assert_eq(err, 0); + count++; + } + + igt_info("%s: count %lu\n", engine->name, count); + igt_spin_free(i915, spin); +} + +static void kill_children(int sig) +{ + signal(sig, SIG_IGN); + kill(-getpgrp(), SIGINT); + signal(sig, SIG_DFL); +} + +static void parallel(int i915) +{ + const struct intel_execution_engine2 *e; + struct drm_i915_gem_relocation_entry *reloc; + uint32_t common = gem_create(i915, 4096); + uint32_t batch = batch_create(i915); + unsigned long reloc_sz; + + reloc = parallel_relocs(32 * 1024, &reloc_sz); + + stop = 0; + __for_each_physical_engine(i915, e) { + igt_fork(child, 1) + parallel_child(i915, e, reloc, common); + } + sleep(2); + + if (gem_scheduler_has_preemption(i915)) { + uint32_t ctx = gem_context_clone_with_engines(i915, 0); + + __for_each_physical_engine(i915, e) { + struct drm_i915_gem_exec_object2 obj[2] = { + { .handle = common }, + { .handle = batch }, + }; + struct drm_i915_gem_execbuffer2 execbuf = { + .buffers_ptr = to_user_pointer(obj), + .buffer_count = ARRAY_SIZE(obj), + .flags = e->flags, + .rsvd1 = ctx, + }; + gem_execbuf(i915, &execbuf); + } + + gem_context_destroy(i915, ctx); + } + gem_sync(i915, batch); + gem_close(i915, batch); + + kill_children(SIGINT); + igt_waitchildren(); + + gem_close(i915, common); + munmap(reloc, reloc_sz); +} + #define CONCURRENT 1024 static uint64_t concurrent_relocs(int i915, int idx, int count) @@ -1284,6 +1493,16 @@ igt_main } } + igt_subtest_with_dynamic("basic-wide-active") { + __for_each_physical_engine(fd, e) { + igt_dynamic_f("%s", e->name) + wide_active(fd, e->flags); + } + } + + igt_subtest("basic-parallel") + parallel(fd); + igt_subtest("basic-concurrent0") concurrent(fd, 0); igt_subtest("basic-concurrent16") |