diff options
| author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-05-12 12:33:32 +0100 |
|---|---|---|
| committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-05-12 13:05:23 +0100 |
| commit | e10c48d9c2c8438b10d4f73e61d579eb8d59ce57 (patch) | |
| tree | 55526f592f7718e2c4629410bd3286606d493cf5 /tests | |
| parent | 31530827e513a5ced092bb1777b0a23a5010af2c (diff) | |
igt/gem_exec_nop: Include the impact of signaling a fence
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/gem_exec_nop.c | 117 |
1 files changed, 116 insertions, 1 deletions
diff --git a/tests/gem_exec_nop.c b/tests/gem_exec_nop.c index 865dbaea..570f57ba 100644 --- a/tests/gem_exec_nop.c +++ b/tests/gem_exec_nop.c @@ -39,6 +39,7 @@ #include <errno.h> #include <sys/stat.h> #include <sys/ioctl.h> +#include <sys/poll.h> #include <sys/time.h> #include <time.h> #include "drm.h" @@ -364,6 +365,7 @@ static int __gem_context_create(int fd, uint32_t *ctx_id) *ctx_id = arg.ctx_id; return ret; } + static void sequential(int fd, uint32_t handle, unsigned flags, int timeout) { const int ncpus = flags & FORKED ? sysconf(_SC_NPROCESSORS_ONLN) : 1; @@ -486,6 +488,113 @@ static void sequential(int fd, uint32_t handle, unsigned flags, int timeout) munmap(results, 4096); } +#define LOCAL_EXEC_FENCE_OUT (1 << 17) +#define LOCAL_IOCTL_I915_GEM_EXECBUFFER2_WR DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2) + +static int __gem_execbuf_wr(int fd, struct drm_i915_gem_execbuffer2 *execbuf) +{ + int err = 0; + if (igt_ioctl(fd, LOCAL_IOCTL_I915_GEM_EXECBUFFER2_WR, execbuf)) + err = -errno; + errno = 0; + return err; +} + +static void gem_execbuf_wr(int fd, struct drm_i915_gem_execbuffer2 *execbuf) +{ + igt_assert_eq(__gem_execbuf_wr(fd, execbuf), 0); +} + +static bool fence_enable_signaling(int fence) +{ + return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0; +} + +static bool fence_wait(int fence) +{ + return poll(&(struct pollfd){fence, POLLIN}, 1, -1) == 1; +} + +static void signal(int fd, uint32_t handle, + unsigned ring_id, const char *ring_name, + int timeout) +{ +#define NFENCES 512 + struct drm_i915_gem_execbuffer2 execbuf; + struct drm_i915_gem_exec_object2 obj; + struct timespec start, now; + unsigned engines[16]; + unsigned nengine; + int *fences, n; + unsigned long count, signal; + + igt_require(gem_has_exec_fence(fd)); + + nengine = 0; + if (ring_id == -1) { + for_each_engine(fd, n) { + if (ignore_engine(fd, n)) + continue; + + engines[nengine++] = n; + } + } else { + engines[nengine++] = ring_id; + } + igt_require(nengine); + + fences = malloc(sizeof(*fences) * NFENCES); + igt_assert(fences); + memset(fences, -1, sizeof(*fences) * NFENCES); + + memset(&obj, 0, sizeof(obj)); + obj.handle = handle; + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(&obj); + execbuf.buffer_count = 1; + execbuf.flags = LOCAL_EXEC_FENCE_OUT; + + n = 0; + count = 0; + signal = 0; + + intel_detect_and_clear_missed_interrupts(fd); + clock_gettime(CLOCK_MONOTONIC, &start); + do { + for (int loop = 0; loop < 1024; loop++) { + for (int e = 0; e < nengine; e++) { + if (fences[n] != -1) { + igt_assert(fence_wait(fences[n])); + close(fences[n]); + } + + execbuf.flags &= ~ENGINE_FLAGS; + execbuf.flags |= engines[e]; + gem_execbuf_wr(fd, &execbuf); + + /* Enable signaling by doing a poll() */ + fences[n] = execbuf.rsvd2 >> 32; + signal += fence_enable_signaling(fences[n]); + + n = (n + 1) % NFENCES; + } + } + + count += 1024 * nengine; + clock_gettime(CLOCK_MONOTONIC, &now); + } while (elapsed(&start, &now) < timeout); + igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0); + + for (n = 0; n < NFENCES; n++) + if (fences[n] != -1) + close(fences[n]); + free(fences); + + igt_info("Signal %s: %'lu cycles (%'lu signals): %.3fus\n", + ring_name, count, signal, elapsed(&start, &now) * 1e6 / count); +} + static void print_welcome(int fd) { bool active; @@ -543,9 +652,15 @@ igt_main igt_subtest("basic-sequential") sequential(device, handle, 0, 5); - for (e = intel_execution_engines; e->name; e++) + for (e = intel_execution_engines; e->name; e++) { igt_subtest_f("%s", e->name) single(device, handle, e->exec_id | e->flags, e->name); + igt_subtest_f("signal-%s", e->name) + signal(device, handle, e->exec_id | e->flags, e->name, 5); + } + + igt_subtest("signal-all") + signal(device, handle, -1, "all", 150); igt_subtest("series") series(device, handle, 150); |
