summaryrefslogtreecommitdiff
path: root/tests/i915/gem_ctx_exec.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2020-02-08 16:08:30 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2020-02-08 17:36:33 +0000
commitff86abde4a54c15dfe7ad70e5a8c75fd41757683 (patch)
treeb65a3071fd1d96b4458a2e2bf730a0dcc938fd1a /tests/i915/gem_ctx_exec.c
parentb7aaa77467742b977b1ea8716d90c7a9a2768220 (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.c82
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);