Even if one client is blocked on a resource, that should not impact another client. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- tests/i915/gem_ctx_exec.c | 122 +++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/tests/i915/gem_ctx_exec.c b/tests/i915/gem_ctx_exec.c index ad2f9e545..d7cd56424 100644 --- a/tests/i915/gem_ctx_exec.c +++ b/tests/i915/gem_ctx_exec.c @@ -35,8 +35,9 @@ #include <fcntl.h> #include <inttypes.h> #include <errno.h> -#include <sys/stat.h> #include <sys/ioctl.h> +#include <sys/poll.h> +#include <sys/stat.h> #include <sys/time.h> #include <drm.h> @@ -331,6 +332,122 @@ static void nohangcheck_hostile(int i915) close(i915); } +static void kill_children(int sig) +{ + sighandler_t old; + + old = signal(sig, SIG_IGN); + kill(-getpgrp(), sig); + signal(sig, old); +} + +static bool has_persistence(int i915) +{ + struct drm_i915_gem_context_param p = { + .param = I915_CONTEXT_PARAM_PERSISTENCE, + }; + uint64_t saved; + + if (__gem_context_get_param(i915, &p)) + return false; + + saved = p.value; + p.value = 0; + if (__gem_context_set_param(i915, &p)) + return false; + + p.value = saved; + return __gem_context_set_param(i915, &p) == 0; +} + +static void pi_active(int i915) +{ + igt_spin_t *spin = igt_spin_new(i915); + unsigned long count = 0; + bool blocked = false; + struct pollfd pfd; + int lnk[2]; + int *done; + + igt_require(gem_scheduler_enabled(i915)); + igt_require(has_persistence(i915)); /* for graceful error recovery */ + + done = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + igt_assert(done != MAP_FAILED); + + igt_assert(pipe(lnk) == 0); + + igt_fork(child, 1) { + struct sigaction sa = { .sa_handler = alarm_handler }; + + sigaction(SIGHUP, &sa, NULL); + + do { + uint32_t ctx; + + if (__gem_context_clone(i915, 0, + I915_CONTEXT_CLONE_ENGINES | + I915_CONTEXT_CLONE_VM, + 0, &ctx)) + break; + + gem_context_set_persistence(i915, ctx, false); + if (READ_ONCE(*done)) + break; + + spin->execbuf.rsvd1 = ctx; + if (__execbuf(i915, &spin->execbuf)) + break; + + count++; + write(lnk[1], &count, sizeof(count)); + } while (1); + } + + pfd.fd = lnk[0]; + pfd.events = POLLIN; + close(lnk[1]); + + igt_until_timeout(90) { + if (poll(&pfd, 1, 1000) == 0) { + igt_info("Child blocked after %lu active contexts\n", + count); + blocked = true; + break; + } + read(pfd.fd, &count, sizeof(count)); + } + + if (blocked) { + struct sigaction old_sa, sa = { .sa_handler = alarm_handler }; + struct itimerval itv; + + sigaction(SIGALRM, &sa, &old_sa); + itv.it_value.tv_sec = 0; + itv.it_value.tv_usec = 250000; /* 250ms */ + setitimer(ITIMER_REAL, &itv, NULL); + + igt_assert_f(__execbuf(i915, &spin->execbuf) == 0, + "Active execbuf blocked for more than 250ms by %lu child contexts\n", + count); + + memset(&itv, 0, sizeof(itv)); + setitimer(ITIMER_REAL, &itv, NULL); + sigaction(SIGALRM, &old_sa, NULL); + } else { + igt_info("Not blocked after %lu active contexts\n", + count); + } + + *done = 1; + kill_children(SIGHUP); + igt_waitchildren(); + gem_quiescent_gpu(i915); + close(lnk[0]); + + munmap(done, 4096); +} + igt_main { const uint32_t batch[2] = { 0, MI_BATCH_BUFFER_END }; @@ -375,6 +492,9 @@ igt_main igt_subtest("basic-nohangcheck") nohangcheck_hostile(fd); + igt_subtest("basic-pi-active") + pi_active(fd); + igt_subtest("reset-pin-leak") { int i; -- 2.26.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx