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

Thomas Wood thomas.wood at intel.com
Fri Oct 16 06:00:42 PDT 2015


On 15 October 2015 at 09:05, Derek Morton <derek.j.morton at intel.com> wrote:
> 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.

Is there any reason not to include this as extra subtests in
gem_exec_nop so that related tests are grouped together?


>
> 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
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx


More information about the Intel-gfx mailing list