summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-02-16 14:42:04 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2016-02-18 09:46:02 +0000
commit3990dd87b60bf8092671cb3c536666936b460b0c (patch)
tree6cc74f7134f210057fe63fdd12a5a548d139fad0
parent3b12d9e6dc115939ddd110c7a7f7ad319b731524 (diff)
igt/gem_ctx_thrash: Combine context thrashing with a render test
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--tests/gem_ctx_thrash.c138
-rw-r--r--tests/gem_wait.c7
2 files changed, 138 insertions, 7 deletions
diff --git a/tests/gem_ctx_thrash.c b/tests/gem_ctx_thrash.c
index 7feedf6f0..129cf4572 100644
--- a/tests/gem_ctx_thrash.c
+++ b/tests/gem_ctx_thrash.c
@@ -63,7 +63,7 @@ static unsigned get_num_contexts(int fd)
return count;
}
-static int has_engine(int fd, const struct intel_execution_engine *e)
+static int has_engine(int fd, const struct intel_execution_engine *e, uint32_t ctx)
{
uint32_t bbe = MI_BATCH_BUFFER_END;
struct drm_i915_gem_execbuffer2 execbuf;
@@ -78,10 +78,137 @@ static int has_engine(int fd, const struct intel_execution_engine *e)
execbuf.buffers_ptr = (uintptr_t)&exec;
execbuf.buffer_count = 1;
execbuf.flags = e->exec_id | e->flags;
+ execbuf.rsvd1 = ctx;
ret = __gem_execbuf(fd, &execbuf);
gem_close(fd, exec.handle);
- return ret == 0;
+ return ret;
+}
+
+static void single(const char *name, bool all_engines)
+{
+ struct drm_i915_gem_exec_object2 *obj;
+ struct drm_i915_gem_relocation_entry *reloc;
+ const struct intel_execution_engine *e;
+ unsigned engines[16];
+ uint64_t size;
+ uint32_t *ctx, *map, scratch;
+ unsigned num_ctx;
+ int fd, gen, num_engines;
+#define MAX_LOOP 16
+
+ fd = drm_open_driver_master(DRIVER_INTEL);
+ gen = intel_gen(intel_get_drm_devid(fd));
+ num_ctx = get_num_contexts(fd);
+
+ num_engines = 0;
+ if (all_engines) {
+ for (e = intel_execution_engines; e->name; e++) {
+ if (e->exec_id == 0)
+ continue;
+
+ if (has_engine(fd, e, 0))
+ continue;
+
+ if (e->exec_id == I915_EXEC_BSD) {
+ int is_bsd2 = e->flags != 0;
+ if (gem_has_bsd2(fd) != is_bsd2)
+ continue;
+ }
+
+ igt_require(has_engine(fd, e, 1) == -ENOENT);
+
+ engines[num_engines++] = e->exec_id | e->flags;
+ if (num_engines == ARRAY_SIZE(engines))
+ break;
+ }
+ } else
+ engines[num_engines++] = 0;
+
+ size = ALIGN(num_ctx * sizeof(uint32_t), 4096);
+ scratch = gem_create(fd, ALIGN(num_ctx * sizeof(uint32_t), 4096));
+ gem_set_caching(fd, scratch, I915_CACHING_CACHED);
+ obj = calloc(num_ctx, 2 * sizeof(*obj));
+ reloc = calloc(num_ctx, sizeof(*reloc));
+
+ ctx = malloc(num_ctx * sizeof(uint32_t));
+ igt_assert(ctx);
+ for (unsigned n = 0; n < num_ctx; n++) {
+ ctx[n] = gem_context_create(fd);
+ obj[2*n + 0].handle = scratch;
+
+ reloc[n].target_handle = scratch;
+ reloc[n].presumed_offset = 0;
+ reloc[n].offset = sizeof(uint32_t);
+ reloc[n].delta = n * sizeof(uint32_t);
+ reloc[n].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+ reloc[n].write_domain = 0; /* lies! */
+ if (gen >= 4 && gen < 8)
+ reloc[n].offset += sizeof(uint32_t);
+
+ obj[2*n + 1].relocs_ptr = (uintptr_t)&reloc[n];
+ obj[2*n + 1].relocation_count = 1;
+ }
+
+ map = gem_mmap__cpu(fd, scratch, 0, size, PROT_WRITE);
+ for (unsigned loop = 1; loop <= MAX_LOOP; loop <<= 1) {
+ unsigned count = loop * num_ctx;
+ uint32_t *all;
+
+ all = malloc(count * sizeof(uint32_t));
+ for (unsigned n = 0; n < count; n++)
+ all[n] = ctx[n % num_ctx];
+ igt_permute_array(all, count, xchg_int);
+ for (unsigned n = 0; n < count; n++) {
+ struct drm_i915_gem_execbuffer2 execbuf;
+ unsigned r = n % num_ctx;
+ uint64_t offset = reloc[r].presumed_offset + reloc[r].delta;
+ uint32_t handle = gem_create(fd, 4096);
+ uint32_t buf[16];
+ int i;
+
+ buf[i = 0] = MI_STORE_DWORD_IMM;
+ if (gen >= 8) {
+ buf[++i] = offset;
+ buf[++i] = offset >> 32;
+ } else if (gen >= 4) {
+ if (gen < 6)
+ buf[i] |= 1 << 22;
+ buf[++i] = 0;
+ buf[++i] = offset;
+ } else {
+ buf[i]--;
+ buf[++i] = offset;
+ }
+ buf[++i] = all[n];
+ buf[++i] = MI_BATCH_BUFFER_END;
+ gem_write(fd, handle, 0, buf, sizeof(buf));
+ obj[2*r + 1].handle = handle;
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = (uintptr_t)&obj[2*r];
+ execbuf.buffer_count = 2;
+ execbuf.flags = engines[n % num_engines];
+ execbuf.rsvd1 = all[n];
+ gem_execbuf(fd, &execbuf);
+ gem_close(fd, handle);
+ }
+
+ /* Note we lied about the write-domain when writing from the
+ * GPU (in order to avoid inter-ring synchronisation), so now
+ * we have to force the synchronisation here.
+ */
+ gem_set_domain(fd, scratch,
+ I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+ for (unsigned n = count - num_ctx; n < count; n++)
+ igt_assert_eq(map[n % num_ctx], all[n]);
+ free(all);
+ igt_progress(name, loop, MAX_LOOP);
+ }
+ munmap(map, size);
+
+ free(ctx);
+ close(fd);
}
static void processes(void)
@@ -102,7 +229,7 @@ static void processes(void)
if (e->exec_id == 0)
continue;
- if (!has_engine(fd, e))
+ if (has_engine(fd, e, 0))
continue;
if (e->exec_id == I915_EXEC_BSD) {
@@ -235,6 +362,11 @@ igt_main
{
igt_skip_on_simulation();
+ igt_subtest("single")
+ single("single", false);
+ igt_subtest("engines")
+ single("engines", true);
+
igt_subtest("processes")
processes();
diff --git a/tests/gem_wait.c b/tests/gem_wait.c
index e1c174b3d..ecf0dcf3d 100644
--- a/tests/gem_wait.c
+++ b/tests/gem_wait.c
@@ -155,7 +155,7 @@ static void render_timeout(int fd)
igt_assert_lt(iter, 1000000);
- igt_info("%d iters is enough work\n", iter);
+ igt_debug("%d iters is enough work\n", iter);
gem_quiescent_gpu(fd);
if (do_signals)
igt_fork_signal_helper();
@@ -174,9 +174,8 @@ static void render_timeout(int fd)
igt_assert_neq(timeout, 0);
if (timeout == (ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC))
igt_info("Buffer was already done!\n");
- else {
- igt_info("Finished with %" PRIu64 " time remaining\n", timeout);
- }
+ else
+ igt_info("Finished with %fs remaining\n", timeout*1e-9);
/* check that polling with timeout=0 works. */
timeout = 0;