summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2020-11-30 11:37:06 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2020-11-30 11:39:06 +0000
commitcf2f41b3d3dfabaf3a4837062f996f3491a350b1 (patch)
tree0fbf5aec0d3c57b82f2468f99b3172e7a97dfc93
parentd1688b297ccd5600cb465dd84685591d63a18026 (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.c219
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")