Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Cc: Mika Kuoppala <mika.kuoppala@xxxxxxxxxxxxxxx> --- tests/Makefile.sources | 1 + tests/gem_ctx_shared.c | 294 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+) create mode 100644 tests/gem_ctx_shared.c diff --git a/tests/Makefile.sources b/tests/Makefile.sources index e4e06d01d..48b3f4625 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -58,6 +58,7 @@ TESTS_progs = \ gem_ctx_create \ gem_ctx_exec \ gem_ctx_param \ + gem_ctx_shared \ gem_ctx_switch \ gem_ctx_thrash \ gem_double_irq_loop \ diff --git a/tests/gem_ctx_shared.c b/tests/gem_ctx_shared.c new file mode 100644 index 000000000..2262fda47 --- /dev/null +++ b/tests/gem_ctx_shared.c @@ -0,0 +1,294 @@ +/* + * Copyright © 2017 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. + * + */ + +#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 <drm.h> + +IGT_TEST_DESCRIPTION("Test shared contexts."); + +struct local_i915_gem_context_create_v2 { + uint32_t ctx_id; + uint32_t flags; +#define I915_GEM_CONTEXT_SHARE_GTT 0x1 + uint32_t share_ctx; + uint32_t pad; +}; + +#define LOCAL_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct local_i915_gem_context_create_v2) + +static int +__gem_context_create_shared(int i915, uint32_t share, unsigned int flags, + uint32_t *out) +{ + struct local_i915_gem_context_create_v2 arg = { + .flags = flags, + .share_ctx = share, + }; + int err = 0; + + if (igt_ioctl(i915, LOCAL_IOCTL_I915_GEM_CONTEXT_CREATE, &arg)) + err = -errno; + + *out = arg.ctx_id; + + errno = 0; + return err; +} + +static uint32_t +gem_context_create_shared(int i915, uint32_t share, unsigned int flags) +{ + uint32_t ctx; + + igt_assert_eq(__gem_context_create_shared(i915, share, flags, &ctx), 0); + + return ctx; +} + +static void create_shared_gtt(int i915, unsigned int flags) +#define DETACHED 0x1 +{ + const uint32_t bbe = MI_BATCH_BUFFER_END; + struct drm_i915_gem_exec_object2 obj = { + .handle = gem_create(i915, 4096), + }; + struct drm_i915_gem_execbuffer2 execbuf = { + .buffers_ptr = to_user_pointer(&obj), + .buffer_count = 1, + }; + uint32_t parent, child; + + gem_write(i915, obj.handle, 0, &bbe, sizeof(bbe)); + gem_execbuf(i915, &execbuf); + gem_sync(i915, obj.handle); + + child = flags & DETACHED ? gem_context_create(i915) : 0; + igt_until_timeout(2) { + parent = flags & DETACHED ? child : 0; + child = gem_context_create_shared(i915, parent, + I915_GEM_CONTEXT_SHARE_GTT); + execbuf.rsvd1 = child; + gem_execbuf(i915, &execbuf); + + if (flags & DETACHED) { + gem_context_destroy(i915, parent); + gem_execbuf(i915, &execbuf); + } else { + parent = child; + gem_context_destroy(i915, parent); + } + + execbuf.rsvd1 = parent; + igt_assert_eq(__gem_execbuf(i915, &execbuf), -ENOENT); + igt_assert_eq(__gem_context_create_shared(i915, parent, + I915_GEM_CONTEXT_SHARE_GTT, + &parent), -ENOENT); + } + if (flags & DETACHED) + gem_context_destroy(i915, child); + + gem_sync(i915, obj.handle); + gem_close(i915, obj.handle); +} + +static int reopen_driver(int fd) +{ + char path[256]; + + snprintf(path, sizeof(path), "/proc/self/fd/%d", fd); + fd = open(path, O_RDWR); + igt_assert_lte(0, fd); + + return fd; +} + +static void exhaust_shared_gtt(int i915, unsigned int flags) +#define EXHAUST_LRC 0x1 +{ + i915 = reopen_driver(i915); + + igt_fork(pid, 1) { + const uint32_t bbe = MI_BATCH_BUFFER_END; + struct drm_i915_gem_exec_object2 obj = { + .handle = gem_create(i915, 4096) + }; + struct drm_i915_gem_execbuffer2 execbuf = { + .buffers_ptr = to_user_pointer(&obj), + .buffer_count = 1, + }; + uint32_t parent, child; + unsigned long count = 0; + int err; + + gem_write(i915, obj.handle, 0, &bbe, sizeof(bbe)); + + child = 0; + for (;;) { + parent = child; + err = __gem_context_create_shared(i915, parent, + I915_GEM_CONTEXT_SHARE_GTT, + &child); + if (err) + break; + + if (flags & EXHAUST_LRC) { + execbuf.rsvd1 = child; + err = __gem_execbuf(i915, &execbuf); + if (err) + break; + } + + count++; + } + gem_sync(i915, obj.handle); + + igt_info("Created %lu shared contexts, before %d (%s)\n", + count, err, strerror(-err)); + } + close(i915); + igt_waitchildren(); +} + +static void exec_shared_gtt(int i915, unsigned int ring) +{ + const int gen = intel_gen(intel_get_drm_devid(i915)); + const uint32_t bbe = MI_BATCH_BUFFER_END; + struct drm_i915_gem_exec_object2 obj = { + .handle = gem_create(i915, 4096) + }; + struct drm_i915_gem_execbuffer2 execbuf = { + .buffers_ptr = to_user_pointer(&obj), + .buffer_count = 1, + .flags = ring, + }; + uint32_t scratch = obj.handle; + uint32_t batch[16]; + int i; + + gem_require_ring(i915, ring); + igt_require(gem_can_store_dword(i915, ring)); + + /* Load object into place in the GTT */ + gem_write(i915, obj.handle, 0, &bbe, sizeof(bbe)); + gem_execbuf(i915, &execbuf); + + /* Presume nothing causes an eviction in the meantime */ + + obj.handle = gem_create(i915, 4096); + + i = 0; + batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0); + if (gen >= 8) { + batch[++i] = obj.offset; + batch[++i] = 0; + } else if (gen >= 4) { + batch[++i] = 0; + batch[++i] = obj.offset; + } else { + batch[i]--; + batch[++i] = obj.offset; + } + batch[++i] = 0xc0ffee; + batch[++i] = MI_BATCH_BUFFER_END; + gem_write(i915, obj.handle, 0, batch, sizeof(batch)); + + obj.offset += 4096; /* make sure we don't cause an eviction! */ + obj.flags |= EXEC_OBJECT_PINNED; + execbuf.rsvd1 = gem_context_create_shared(i915, 0, + I915_GEM_CONTEXT_SHARE_GTT); + if (gen > 3 && gen < 6) + execbuf.flags |= I915_EXEC_SECURE; + + gem_execbuf(i915, &execbuf); + gem_context_destroy(i915, execbuf.rsvd1); + gem_sync(i915, obj.handle); /* write hazard lies */ + gem_close(i915, obj.handle); + + gem_read(i915, scratch, 0, batch, sizeof(uint32_t)); + gem_close(i915, scratch); + + igt_assert_eq_u32(*batch, 0xc0ffee); +} + +static bool has_share_gtt(int i915) +{ + uint32_t ctx; + + __gem_context_create_shared(i915, 0, I915_GEM_CONTEXT_SHARE_GTT, &ctx); + if (ctx) + gem_context_destroy(i915, ctx); + + return ctx != 0; +} + +igt_main +{ + const struct intel_execution_engine *e; + int i915; + + igt_fixture { + i915 = drm_open_driver(DRIVER_INTEL); + igt_require_gem(i915); + } + + igt_subtest_group { + igt_fixture { + igt_require(has_share_gtt(i915)); + igt_fork_hang_detector(i915); + } + + igt_subtest("create-shared-gtt") + create_shared_gtt(i915, 0); + + igt_subtest("detached-shared-gtt") + create_shared_gtt(i915, DETACHED); + + igt_subtest("exhaust-shared-gtt") + exhaust_shared_gtt(i915, 0); + + igt_subtest("exhaust-shared-gtt-lrc") + exhaust_shared_gtt(i915, EXHAUST_LRC); + + for (e = intel_execution_engines; e->name; e++) { + igt_subtest_f("exec-shared-gtt-%s", e->name) + exec_shared_gtt(i915, e->exec_id | e->flags); + } + + igt_fixture { + igt_stop_hang_detector(); + } + } +} -- 2.15.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx