[Intel-gfx] [PATCH i-g-t] tests: Add gem_exec_nop_concurrent test

Derek Morton derek.j.morton at intel.com
Thu Oct 15 01:05:44 PDT 2015


This test is based on gem_exec_nop but submits nop batch buffers concurrently
from different threads to check for ring hangs and other issues during
concurrent submissions.

Signed-off-by: Derek Morton <derek.j.morton at intel.com>
---
 tests/.gitignore                |   1 +
 tests/Makefile.sources          |   1 +
 tests/gem_exec_nop_concurrent.c | 172 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 174 insertions(+)
 create mode 100644 tests/gem_exec_nop_concurrent.c

diff --git a/tests/.gitignore b/tests/.gitignore
index dc8bb53..0ad36f3 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -46,6 +46,7 @@ gem_exec_blt
 gem_exec_faulting_reloc
 gem_exec_lut_handle
 gem_exec_nop
+gem_exec_nop_concurrent
 gem_exec_params
 gem_exec_parse
 gem_fd_exhaustion
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 2e2e088..aece831 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -27,6 +27,7 @@ TESTS_progs_M = \
 	gem_exec_bad_domains \
 	gem_exec_faulting_reloc \
 	gem_exec_nop \
+	gem_exec_nop_concurrent \
 	gem_exec_params \
 	gem_exec_parse \
 	gem_fenced_exec_thrash \
diff --git a/tests/gem_exec_nop_concurrent.c b/tests/gem_exec_nop_concurrent.c
new file mode 100644
index 0000000..578f651
--- /dev/null
+++ b/tests/gem_exec_nop_concurrent.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Derek Morton <derek.j.morton at intel.com>
+ *
+ * This test is based on gem_exec_nop but submits nop batch buffers concurrently
+ * from different threads to check for ring hangs and other issues during
+ * concurrent submissions.
+ *
+ */
+
+#include "igt.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <time.h>
+#include "drm.h"
+
+#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
+#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
+
+#define LOCAL_I915_EXEC_VEBOX (4<<0)
+
+IGT_TEST_DESCRIPTION(
+    "This Test will submit nop batch buffers concurrently to the same ring "
+     "and different rings in an attempt to trigger ring hangs.");
+
+const uint32_t batch[2] = {MI_BATCH_BUFFER_END};
+
+struct ring
+{
+	unsigned ring_id;
+	const char *ring_name;
+	bool direction;
+};
+
+static void loop(int fd, uint32_t handle, int child_nbr, struct ring* ring, bool up)
+{
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 gem_exec[1];
+	int count;
+	int max_count = SLOW_QUICK(15, 4);
+
+	gem_require_ring(fd, ring->ring_id);
+
+	memset(&gem_exec, 0, sizeof(gem_exec));
+	gem_exec[0].handle = handle;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = (uintptr_t)gem_exec;
+	execbuf.buffer_count = 1;
+	execbuf.flags = ring->ring_id;
+	execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
+	execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
+	if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)) {
+		execbuf.flags = ring->ring_id;
+		do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
+	}
+	gem_sync(fd, handle);
+
+	for (count = 0; count <= max_count; count++) {
+		const int reps = 7;
+		int n, nbr_loops;
+
+		if (up)
+			nbr_loops = 1 << count;
+		else
+			nbr_loops = 1 << (max_count - count);
+
+		igt_info("Thread %d: starting submitting batches of %d batch buffers (ring=%s)\n",
+			 child_nbr, nbr_loops, ring->ring_name);
+		fflush(stdout);
+
+		for (n = 0; n < reps; n++) {
+			int loops = nbr_loops;
+
+			while (loops--)
+				do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
+			gem_sync(fd, handle);
+		}
+
+		igt_info("Thread %d: finished submitting batches of %d batch buffers (ring=%s)\n",
+			 child_nbr, nbr_loops, ring->ring_name);
+		fflush(stdout);
+	}
+}
+
+static void run_forked(struct ring rings[])
+{
+	int nbr_rings = 0;
+	while (rings[nbr_rings].ring_name != NULL)
+		nbr_rings++;
+
+	igt_fork(child, nbr_rings) {
+		int fd;
+		uint32_t handle;
+
+		fd = drm_open_driver(DRIVER_INTEL);
+
+		handle = gem_create(fd, 4096);
+		gem_write(fd, handle, 0, batch, sizeof(batch));
+
+		igt_info("Starting thread %d on ring %s\n", child, rings[child].ring_name);
+		fflush(stdout);
+		loop(fd, handle, child, &rings[child], rings[child].direction);
+
+		gem_close(fd, handle);
+
+		close(fd);
+	}
+	igt_waitchildren();
+}
+
+igt_main
+{
+	struct ring all_rings[] = {
+		{I915_EXEC_RENDER, "render", 1},
+		{I915_EXEC_BSD, "bsd", 1},
+		{I915_EXEC_BLT, "blt", 1},
+		{LOCAL_I915_EXEC_VEBOX, "vebox", 1},
+		{ 0, NULL, 0 },
+	},
+	rings[] = {
+		{ 0, NULL, 1 },
+		{ 0, NULL, 0 },
+		{ 0, NULL, 0 },
+	}, *t1, *t2;
+
+	for (t1 = all_rings; t1->ring_name; t1++) {
+		rings[0].ring_id = t1->ring_id;
+		rings[0].ring_name = t1->ring_name;
+
+		for (t2 = all_rings; t2->ring_name; t2++) {
+			rings[1].ring_id = t2->ring_id;
+			rings[1].ring_name = t2->ring_name;
+
+			igt_subtest_f("%s-%s",t1->ring_name, t2->ring_name)
+				run_forked(rings);
+		}
+	}
+	igt_subtest("all-rings")
+		run_forked(all_rings);
+
+}
-- 
1.9.1



More information about the Intel-gfx mailing list