[PATCH i-g-t] i915: Add gem_cancel
Chris Wilson
chris at chris-wilson.co.uk
Thu Dec 10 16:06:31 UTC 2020
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
lib/igt_dummyload.c | 5 +
lib/igt_dummyload.h | 17 +--
tests/Makefile.sources | 3 +
tests/i915/gem_cancel.c | 177 +++++++++++++++++++++++++++++++
tests/i915/gem_ctx_persistence.c | 2 +-
tests/meson.build | 1 +
6 files changed, 196 insertions(+), 9 deletions(-)
create mode 100644 tests/i915/gem_cancel.c
diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
index 31cfb0697..28bbd3622 100644
--- a/lib/igt_dummyload.c
+++ b/lib/igt_dummyload.c
@@ -333,6 +333,11 @@ emit_recursive_batch(igt_spin_t *spin,
execbuf->rsvd2 = opts->fence;
}
+ if (opts->flags & IGT_SPIN_FENCE_SUBMIT) {
+ execbuf->flags |= I915_EXEC_FENCE_SUBMIT;
+ execbuf->rsvd2 = opts->fence;
+ }
+
for (i = 0; i < nengine; i++) {
execbuf->flags &= ~ENGINE_MASK;
execbuf->flags |= flags[i];
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
index 232f3238e..c38f9efd8 100644
--- a/lib/igt_dummyload.h
+++ b/lib/igt_dummyload.h
@@ -65,14 +65,15 @@ struct igt_spin_factory {
};
#define IGT_SPIN_FENCE_IN (1 << 0)
-#define IGT_SPIN_FENCE_OUT (1 << 1)
-#define IGT_SPIN_POLL_RUN (1 << 2)
-#define IGT_SPIN_WAKE_RUN (1 << 3)
-#define IGT_SPIN_FAST (1 << 4)
-#define IGT_SPIN_NO_PREEMPTION (1 << 5)
-#define IGT_SPIN_INVALID_CS (1 << 6)
-#define IGT_SPIN_USERPTR (1 << 7)
-#define IGT_SPIN_SOFTDEP (1 << 8)
+#define IGT_SPIN_FENCE_SUBMIT (1 << 1)
+#define IGT_SPIN_FENCE_OUT (1 << 2)
+#define IGT_SPIN_POLL_RUN (1 << 3)
+#define IGT_SPIN_WAKE_RUN (1 << 4)
+#define IGT_SPIN_FAST (1 << 5)
+#define IGT_SPIN_NO_PREEMPTION (1 << 6)
+#define IGT_SPIN_INVALID_CS (1 << 7)
+#define IGT_SPIN_USERPTR (1 << 8)
+#define IGT_SPIN_SOFTDEP (1 << 9)
igt_spin_t *
__igt_spin_factory(int fd, const struct igt_spin_factory *opts);
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index b4a472623..8b23237ae 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -461,6 +461,9 @@ gem_unref_active_buffers_SOURCES = i915/gem_unref_active_buffers.c
TESTS_progs += gem_userptr_blits
gem_userptr_blits_SOURCES = i915/gem_userptr_blits.c
+TESTS_progs += gem_cancel
+gem_cancel_SOURCES = i915/gem_cancel.c
+
TESTS_progs += gem_wait
gem_wait_SOURCES = i915/gem_wait.c
diff --git a/tests/i915/gem_cancel.c b/tests/i915/gem_cancel.c
new file mode 100644
index 000000000..0060eb953
--- /dev/null
+++ b/tests/i915/gem_cancel.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#include <unistd.h>
+
+#include "drmtest.h"
+#include "i915/gem.h"
+#include "i915/gem_engine_topology.h"
+#include "igt_core.h"
+#include "igt_dummyload.h"
+#include "ioctl_wrappers.h"
+#include "sw_sync.h"
+
+#define DRM_I915_GEM_CANCEL 0x3c
+#define DRM_IOCTL_I915_GEM_CANCEL DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CANCEL, struct drm_i915_gem_cancel)
+struct drm_i915_gem_cancel {
+ __u32 handle;
+ __u32 flags;
+#define CANCEL_SYNCOBJ (1 << 0)
+};
+
+static int __gem_cancel(int i915, uint32_t handle, uint32_t flags)
+{
+ struct drm_i915_gem_cancel arg = {
+ .handle = handle,
+ .flags = flags,
+ };
+ int err;
+
+ err = 0;
+ if (igt_ioctl(i915, DRM_IOCTL_I915_GEM_CANCEL, &arg)) {
+ err = -errno;
+ igt_assume(err);
+ }
+
+ errno = 0;
+ return err;
+}
+
+static void gem_cancel(int i915, uint32_t handle, uint32_t flags)
+{
+ igt_assert_eq(__gem_cancel(i915, handle, flags), 0);
+}
+
+static bool has_cancel(int i915)
+{
+ return __gem_cancel(i915, -1, 0) == -ENOENT;
+}
+
+static void test_active(int i915, unsigned int engine)
+{
+ igt_spin_t *spin;
+
+ spin = igt_spin_new(i915,
+ .engine = engine,
+ .flags = IGT_SPIN_POLL_RUN | IGT_SPIN_FENCE_OUT);
+ igt_spin_busywait_until_started(spin);
+
+ gem_cancel(i915, spin->out_fence, 0);
+ igt_assert_eq(sync_fence_wait(spin->out_fence, 50), 0);
+ igt_assert_eq(sync_fence_status(spin->out_fence), -EINTR);
+
+ igt_spin_free(i915, spin);
+}
+
+static void test_signaled(int i915, unsigned int engine)
+{
+ igt_spin_t *spin;
+
+ spin = igt_spin_new(i915,
+ .engine = engine,
+ .flags = IGT_SPIN_POLL_RUN | IGT_SPIN_FENCE_OUT);
+ igt_spin_busywait_until_started(spin);
+ igt_spin_end(spin);
+ igt_assert_eq(sync_fence_wait(spin->out_fence, 50), 0);
+
+ gem_cancel(i915, spin->out_fence, 0);
+ igt_assert_eq(sync_fence_status(spin->out_fence), 1);
+
+ igt_spin_free(i915, spin);
+}
+
+static void test_unready(int i915, unsigned int engine)
+{
+ igt_spin_t *spin[2];
+
+ spin[0] = igt_spin_new(i915,
+ .engine = engine,
+ .flags = IGT_SPIN_POLL_RUN);
+ igt_spin_busywait_until_started(spin[0]);
+
+ spin[1] = igt_spin_new(i915,
+ .engine = engine,
+ .flags = IGT_SPIN_FENCE_OUT);
+
+ gem_cancel(i915, spin[1]->out_fence, 0);
+ igt_spin_end(spin[0]);
+
+ igt_assert_eq(sync_fence_wait(spin[1]->out_fence, 50), 0);
+ igt_assert_eq(sync_fence_status(spin[1]->out_fence), -EINTR);
+
+ igt_spin_free(i915, spin[1]);
+ igt_spin_free(i915, spin[0]);
+}
+
+static void test_parallel(int i915)
+{
+ struct intel_execution_engine2 *e;
+ int first = -1;
+ int last = -1;
+
+ __for_each_physical_engine(i915, e) {
+ igt_spin_t *spin;
+
+ spin = igt_spin_new(i915,
+ .engine = e->flags,
+ .fence = last,
+ .flags = (IGT_SPIN_POLL_RUN |
+ IGT_SPIN_FENCE_OUT |
+ (last != -1 ? IGT_SPIN_FENCE_SUBMIT : 0)));
+ igt_spin_busywait_until_started(spin);
+
+ last = spin->out_fence;
+ if (first == -1)
+ first = last;
+ }
+ igt_require(first != -1);
+
+ gem_cancel(i915, first, 0);
+ igt_assert_eq(sync_fence_wait(last, 50), 0);
+ igt_assert_eq(sync_fence_status(last), -EINTR);
+
+ gem_quiescent_gpu(i915);
+}
+
+igt_main
+{
+ struct intel_execution_engine2 *e;
+ int i915;
+
+ igt_fixture {
+ i915 = drm_open_driver(DRIVER_INTEL);
+ igt_require_gem(i915);
+
+ igt_require(has_cancel(i915));
+ }
+
+ igt_subtest_with_dynamic("active") {
+ __for_each_physical_engine(i915, e) {
+ igt_dynamic_f("%s", e->name)
+ test_active(i915, e->flags);
+ }
+ }
+
+ igt_subtest_with_dynamic("signaled") {
+ __for_each_physical_engine(i915, e) {
+ igt_dynamic_f("%s", e->name)
+ test_signaled(i915, e->flags);
+ }
+ }
+
+ igt_subtest_with_dynamic("unready") {
+ __for_each_physical_engine(i915, e) {
+ igt_dynamic_f("%s", e->name)
+ test_unready(i915, e->flags);
+ }
+ }
+
+ igt_subtest("parallel")
+ test_parallel(i915);
+
+ igt_fixture {
+ close(i915);
+ }
+}
diff --git a/tests/i915/gem_ctx_persistence.c b/tests/i915/gem_ctx_persistence.c
index 97b38e780..ebbf33308 100644
--- a/tests/i915/gem_ctx_persistence.c
+++ b/tests/i915/gem_ctx_persistence.c
@@ -783,7 +783,7 @@ static void test_userptr(int i915)
fence = recvfd(sv[1]);
close(sv[1]);
- igt_assert_eq(wait_for_status(fence, reset_timeout_ms), -EIO);
+ igt_assert_eq(wait_for_status(i915, fence, reset_timeout_ms), -EIO);
close(fence);
/* We have to manually clean up the orphaned spinner */
diff --git a/tests/meson.build b/tests/meson.build
index 86dbae950..b77627e86 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -121,6 +121,7 @@ i915_progs = [
'gem_blits',
'gem_busy',
'gem_caching',
+ 'gem_cancel',
'gem_close',
'gem_close_race',
'gem_concurrent_blit',
--
2.29.2
More information about the Intel-gfx-trybot
mailing list