diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2020-02-08 16:08:30 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2020-02-08 17:36:33 +0000 |
commit | ff86abde4a54c15dfe7ad70e5a8c75fd41757683 (patch) | |
tree | b65a3071fd1d96b4458a2e2bf730a0dcc938fd1a /tests/i915/gem_ctx_exec.c | |
parent | b7aaa77467742b977b1ea8716d90c7a9a2768220 (diff) |
i915/gem_ctx_exec: Flood the nohangcheck with spinners
One hostile request is easily to defeat, but we tripped over dealing
with a couple! Maximise the evil!
References: https://gitlab.freedesktop.org/drm/intel/issues/1166
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Andi Shyti <andi.shyti@intel.com>
Diffstat (limited to 'tests/i915/gem_ctx_exec.c')
-rw-r--r-- | tests/i915/gem_ctx_exec.c | 82 |
1 files changed, 72 insertions, 10 deletions
diff --git a/tests/i915/gem_ctx_exec.c b/tests/i915/gem_ctx_exec.c index 5b4e4b3d..ad2f9e54 100644 --- a/tests/i915/gem_ctx_exec.c +++ b/tests/i915/gem_ctx_exec.c @@ -27,6 +27,7 @@ #include "igt.h" #include <limits.h> #include <unistd.h> +#include <signal.h> #include <stdlib.h> #include <stdint.h> #include <stdio.h> @@ -202,6 +203,63 @@ static bool __enable_hangcheck(int dir, bool state) return igt_sysfs_set(dir, "enable_hangcheck", state ? "1" : "0"); } +static int __execbuf(int i915, struct drm_i915_gem_execbuffer2 *execbuf) +{ + int err; + + err = 0; + if (ioctl(i915, DRM_IOCTL_I915_GEM_EXECBUFFER2_WR, execbuf)) { + err = -errno; + igt_assume(err); + } + + errno = 0; + return err; +} + +static void alarm_handler(int sig) +{ +} + +static int fill_ring(int i915, struct drm_i915_gem_execbuffer2 *execbuf) +{ + struct sigaction old_sa, sa = { .sa_handler = alarm_handler }; + int fence = execbuf->rsvd2 >> 32; + struct itimerval itv; + bool once = false; + + sigaction(SIGALRM, &sa, &old_sa); + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = 1000; + itv.it_value.tv_sec = 0; + itv.it_value.tv_usec = 10000; + setitimer(ITIMER_REAL, &itv, NULL); + + igt_assert(execbuf->flags & I915_EXEC_FENCE_OUT); + do { + int err = __execbuf(i915, execbuf); + + if (err == 0) { + close(fence); + fence = execbuf->rsvd2 >> 32; + continue; + } + + if (err == -EWOULDBLOCK || once) + break; + + /* sleep until the next timer interrupt (woken on signal) */ + pause(); + once = true; + } while (1); + + memset(&itv, 0, sizeof(itv)); + setitimer(ITIMER_REAL, &itv, NULL); + sigaction(SIGALRM, &old_sa, NULL); + + return fence; +} + static void nohangcheck_hostile(int i915) { const struct intel_execution_engine2 *e; @@ -228,23 +286,27 @@ static void nohangcheck_hostile(int i915) ____for_each_physical_engine(i915, ctx, e) { igt_spin_t *spin; + int new; + + spin = __igt_spin_new(i915, ctx, + .engine = e->flags, + .flags = (IGT_SPIN_NO_PREEMPTION | + IGT_SPIN_FENCE_OUT)); - spin = igt_spin_new(i915, ctx, - .engine = e->flags, - .flags = (IGT_SPIN_NO_PREEMPTION | - IGT_SPIN_FENCE_OUT)); + new = fill_ring(i915, &spin->execbuf); + igt_assert(new != -1); + spin->out_fence = -1; - igt_assert(spin->out_fence != -1); if (fence < 0) { - fence = spin->out_fence; - spin->out_fence = -1; + fence = new; } else { - int new; + int tmp; - new = sync_fence_merge(fence, spin->out_fence); + tmp = sync_fence_merge(fence, new); close(fence); + close(new); - fence = new; + fence = tmp; } } gem_context_destroy(i915, ctx); |