summaryrefslogtreecommitdiff
path: root/tests/i915/gem_exec_fence.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2020-05-06 15:05:23 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2020-05-06 20:13:12 +0100
commit294f767a6834d376ab0bc0c585aba5398c17f701 (patch)
treee31e3f8973857ea422d018d66d1cdba233f18788 /tests/i915/gem_exec_fence.c
parentdc5ce45b20db80c97988c5efdf8869f88c14584a (diff)
i915/gem_exec_fence: Exercise timeslicing on submit-fence
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Diffstat (limited to 'tests/i915/gem_exec_fence.c')
-rw-r--r--tests/i915/gem_exec_fence.c139
1 files changed, 127 insertions, 12 deletions
diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 3d446ffb..c30eeb12 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -46,6 +46,15 @@ struct sync_merge_data {
#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
#endif
+#define MI_SEMAPHORE_WAIT (0x1c << 23)
+#define MI_SEMAPHORE_POLL (1 << 15)
+#define MI_SEMAPHORE_SAD_GT_SDD (0 << 12)
+#define MI_SEMAPHORE_SAD_GTE_SDD (1 << 12)
+#define MI_SEMAPHORE_SAD_LT_SDD (2 << 12)
+#define MI_SEMAPHORE_SAD_LTE_SDD (3 << 12)
+#define MI_SEMAPHORE_SAD_EQ_SDD (4 << 12)
+#define MI_SEMAPHORE_SAD_NEQ_SDD (5 << 12)
+
static void store(int fd, const struct intel_execution_engine2 *e,
int fence, uint32_t target, unsigned offset_value)
{
@@ -376,6 +385,109 @@ static void test_fence_await(int fd, const struct intel_execution_engine2 *e,
gem_close(fd, scratch);
}
+static uint32_t timeslicing_batches(int i915, uint32_t *offset)
+{
+ uint32_t handle = gem_create(i915, 4096);
+ uint32_t cs[256];
+
+ *offset += 4000;
+ for (int pair = 0; pair <= 1; pair++) {
+ int x = 1;
+ int i = 0;
+
+ for (int step = 0; step < 8; step++) {
+ if (pair) {
+ cs[i++] =
+ MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_EQ_SDD |
+ (4 - 2);
+ cs[i++] = x++;
+ cs[i++] = *offset;
+ cs[i++] = 0;
+ }
+
+ cs[i++] = MI_STORE_DWORD_IMM;
+ cs[i++] = *offset;
+ cs[i++] = 0;
+ cs[i++] = x++;
+
+ if (!pair) {
+ cs[i++] =
+ MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_EQ_SDD |
+ (4 - 2);
+ cs[i++] = x++;
+ cs[i++] = *offset;
+ cs[i++] = 0;
+ }
+ }
+
+ cs[i++] = MI_BATCH_BUFFER_END;
+ igt_assert(i < ARRAY_SIZE(cs));
+ gem_write(i915, handle, pair * sizeof(cs), cs, sizeof(cs));
+ }
+
+ *offset = sizeof(cs);
+ return handle;
+}
+
+static void test_submit_fence(int i915, unsigned int engine)
+{
+ const struct intel_execution_engine2 *e;
+
+ /*
+ * Create a pair of interlocking batches, that ping pong
+ * between each other, and only advance one step at a time.
+ * We require the kernel to preempt at each semaphore and
+ * switch to the other batch in order to advance.
+ */
+
+ __for_each_physical_engine(i915, e) {
+ unsigned int offset = 24 << 20;
+ struct drm_i915_gem_exec_object2 obj = {
+ .offset = offset,
+ .flags = EXEC_OBJECT_PINNED,
+ };
+ struct drm_i915_gem_execbuffer2 execbuf = {
+ .buffers_ptr = to_user_pointer(&obj),
+ .buffer_count = 1,
+ };
+ uint32_t result;
+ int out;
+
+ obj.handle = timeslicing_batches(i915, &offset);
+
+ execbuf.flags = engine | I915_EXEC_FENCE_OUT;
+ execbuf.batch_start_offset = 0;
+ gem_execbuf_wr(i915, &execbuf);
+
+ execbuf.rsvd1 = gem_context_clone_with_engines(i915, 0);
+ execbuf.rsvd2 >>= 32;
+ execbuf.flags = e->flags;
+ execbuf.flags |= I915_EXEC_FENCE_SUBMIT | I915_EXEC_FENCE_OUT;
+ execbuf.batch_start_offset = offset;
+ gem_execbuf_wr(i915, &execbuf);
+ gem_context_destroy(i915, execbuf.rsvd1);
+
+ gem_sync(i915, obj.handle);
+
+ /* no hangs! */
+ out = execbuf.rsvd2;
+ igt_assert_eq(sync_fence_status(out), 1);
+ close(out);
+
+ out = execbuf.rsvd2 >> 32;
+ igt_assert_eq(sync_fence_status(out), 1);
+ close(out);
+
+ gem_read(i915, obj.handle, 4000, &result, sizeof(result));
+ igt_assert_eq(result, 16);
+ gem_close(i915, obj.handle);
+ }
+}
+
static void alarm_handler(int sig)
{
}
@@ -1333,32 +1445,28 @@ igt_main
igt_subtest_group {
igt_fixture {
igt_fork_hang_detector(i915);
- }
+ }
+
igt_subtest_with_dynamic("basic-busy") {
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
-
igt_dynamic_f("%s", e->name)
test_fence_busy(i915, e, 0);
}
}
igt_subtest_with_dynamic("basic-wait") {
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
igt_dynamic_f("%s", e->name)
test_fence_busy(i915, e, WAIT);
}
}
igt_subtest_with_dynamic("basic-await") {
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
igt_dynamic_f("%s", e->name)
test_fence_await(i915, e, 0);
}
}
igt_subtest_with_dynamic("nb-await") {
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
igt_dynamic_f("%s", e->name)
test_fence_await(i915,
e, NONBLOCK);
@@ -1366,7 +1474,6 @@ igt_main
}
igt_subtest_with_dynamic("keep-in-fence") {
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
igt_dynamic_f("%s", e->name)
test_keep_in_fence(i915, e);
}
@@ -1374,7 +1481,6 @@ igt_main
igt_subtest_with_dynamic("parallel") {
igt_require(has_submit_fence(i915));
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
igt_dynamic_f("%s", e->name) {
igt_until_timeout(2)
test_parallel(i915, e);
@@ -1382,6 +1488,17 @@ igt_main
}
}
+ igt_subtest_with_dynamic("submit") {
+ igt_require(gem_scheduler_has_semaphores(i915));
+ igt_require(gem_scheduler_has_preemption(i915));
+ igt_require(intel_gen(intel_get_drm_devid(i915)) >= 8);
+
+ __for_each_physical_engine(i915, e) {
+ igt_dynamic_f("%s", e->name)
+ test_submit_fence(i915, e->flags);
+ }
+ }
+
igt_fixture {
igt_stop_hang_detector();
}
@@ -1393,30 +1510,27 @@ igt_main
igt_fixture {
hang = igt_allow_hang(i915, 0, 0);
}
+
igt_subtest_with_dynamic("busy-hang") {
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
igt_dynamic_f("%s", e->name)
test_fence_busy(i915, e, HANG);
}
}
igt_subtest_with_dynamic("wait-hang") {
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
igt_dynamic_f("%s", e->name)
test_fence_busy(i915, e, HANG | WAIT);
}
}
igt_subtest_with_dynamic("await-hang") {
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
igt_dynamic_f("%s", e->name)
test_fence_await(i915, e, HANG);
}
}
igt_subtest_with_dynamic("nb-await-hang") {
__for_each_physical_engine(i915, e) {
- /* Requires master for STORE_DWORD on gen4/5 */
igt_dynamic_f("%s", e->name)
test_fence_await(i915, e, NONBLOCK | HANG);
}
@@ -1486,6 +1600,7 @@ igt_main
igt_stop_hang_detector();
}
}
+
igt_fixture {
close(i915);
}