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.mor...@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.mor...@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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to