diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-04-15 10:39:36 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-04-15 10:58:14 +0100 |
commit | 4233b59608ce655298228b8b606aed0461c7af77 (patch) | |
tree | f0f9174a30a31fc8f84cb57f0f014f92388462c7 | |
parent | 082fb26ce92442493543104d06af3a86382a4a8b (diff) |
igt/gem_busy: Slow down the writer
Add a few more (128) loops to the page full of MI_STORE_DWORD in an
attempt to try and slow down the execution to the point where a
full-debug kernel can beat the GPU.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | tests/gem_busy.c | 121 |
1 files changed, 93 insertions, 28 deletions
diff --git a/tests/gem_busy.c b/tests/gem_busy.c index 372eb451..ddb19916 100644 --- a/tests/gem_busy.c +++ b/tests/gem_busy.c @@ -222,17 +222,68 @@ static void semaphore(int fd, unsigned ring, uint32_t flags) gem_close(fd, handle[i]); } +static void create_indirect(int fd, + struct drm_i915_gem_exec_object2 *obj, + struct drm_i915_gem_exec_object2 *target) +{ + const int gen = intel_gen(intel_get_drm_devid(fd)); + const int nreloc = 128; + struct drm_i915_gem_relocation_entry *reloc; + uint32_t *batch; + int i, count; + + reloc = calloc(nreloc, sizeof(*reloc)); + + obj->handle = gem_create(fd, 4096); + obj->relocs_ptr = (uintptr_t)reloc; + obj->relocation_count = nreloc; + + batch = gem_mmap__cpu(fd, obj->handle, 0, 4096, PROT_WRITE); + gem_set_domain(fd, obj->handle, + I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); + + i = 0; + for (count = 0; count < nreloc; count++) { + reloc[count].target_handle = target->handle; + reloc[count].presumed_offset = target->offset; + reloc[count].offset = sizeof(uint32_t) * (i + 1); + reloc[count].delta = 0; + reloc[count].read_domains = I915_GEM_DOMAIN_COMMAND; + reloc[count].write_domain = 0; + batch[i] = MI_BATCH_BUFFER_START; + if (gen >= 8) { + batch[i] |= 1 << 8 | 1; + batch[++i] = target->offset; + batch[++i] = target->offset >> 32; + } else if (gen >= 6) { + batch[i] |= 1 << 8; + batch[++i] = target->offset; + } else { + batch[i] |= 2 << 6; + batch[++i] = target->offset; + if (gen < 4) { + batch[i] |= 1; + reloc[count].delta = 1; + } + } + i++; + } + batch[++i] = MI_BATCH_BUFFER_END; + igt_assert(i < 4096/sizeof(*batch)); + munmap(batch, 4096); +} + static void store(int fd, unsigned ring, uint32_t flags) { const int gen = intel_gen(intel_get_drm_devid(fd)); - struct drm_i915_gem_exec_object2 obj[2]; - struct drm_i915_gem_relocation_entry reloc[1024]; + struct drm_i915_gem_exec_object2 obj[16]; + struct drm_i915_gem_relocation_entry store[1024]; struct drm_i915_gem_execbuffer2 execbuf; - unsigned size = ALIGN(ARRAY_SIZE(reloc)*16 + 4, 4096); + unsigned size = ALIGN(ARRAY_SIZE(store)*16 + 4, 4096); uint32_t read[2], write[2]; struct timespec tv; uint32_t *batch; - int i, count; + int i, count, idx; gem_require_ring(fd, ring | flags); igt_skip_on_f(gen == 6 && (ring & ~(3<<13)) == I915_EXEC_BSD, @@ -252,22 +303,22 @@ static void store(int fd, unsigned ring, uint32_t flags) obj[0].flags = EXEC_OBJECT_WRITE; obj[1].handle = gem_create(fd, size); - memset(reloc, 0, sizeof(reloc)); - obj[1].relocs_ptr = (uintptr_t)reloc; - obj[1].relocation_count = ARRAY_SIZE(reloc); + memset(store, 0, sizeof(store)); + obj[1].relocs_ptr = (uintptr_t)store; + obj[1].relocation_count = ARRAY_SIZE(store); batch = gem_mmap__cpu(fd, obj[1].handle, 0, size, PROT_WRITE); gem_set_domain(fd, obj[1].handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); i = 0; - for (count = 0; count < ARRAY_SIZE(reloc); count++) { - reloc[count].target_handle = obj[0].handle; - reloc[count].presumed_offset = 0; - reloc[count].offset = sizeof(uint32_t) * (i + 1); - reloc[count].delta = 0; - reloc[count].read_domains = I915_GEM_DOMAIN_INSTRUCTION; - reloc[count].write_domain = I915_GEM_DOMAIN_INSTRUCTION; + for (count = 0; count < ARRAY_SIZE(store); count++) { + store[count].target_handle = obj[0].handle; + store[count].presumed_offset = -1; + store[count].offset = sizeof(uint32_t) * (i + 1); + store[count].delta = sizeof(uint32_t) * count; + store[count].read_domains = I915_GEM_DOMAIN_INSTRUCTION; + store[count].write_domain = I915_GEM_DOMAIN_INSTRUCTION; batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0); if (gen >= 8) { batch[++i] = 0; @@ -275,44 +326,58 @@ static void store(int fd, unsigned ring, uint32_t flags) } else if (gen >= 4) { batch[++i] = 0; batch[++i] = 0; - reloc[count].offset += sizeof(uint32_t); + store[count].offset += sizeof(uint32_t); } else { batch[i]--; batch[++i] = 0; } - batch[++i] = 0xc0ffee; + batch[++i] = count; i++; } batch[++i] = MI_BATCH_BUFFER_END; + igt_assert(i < size/sizeof(*batch)); munmap(batch, size); igt_require(__gem_execbuf(fd, &execbuf) == 0); - count = 16; do { - for (i = 0; i < count; i++) - gem_execbuf(fd, &execbuf); + idx = execbuf.buffer_count++; + igt_require(idx < ARRAY_SIZE(obj)); + create_indirect(fd, &obj[idx], &obj[idx-1]); + igt_require(__gem_execbuf(fd, &execbuf) == 0); + + gem_execbuf(fd, &execbuf); __gem_busy(fd, obj[0].handle, &read[0], &write[0]); - __gem_busy(fd, obj[1].handle, &read[1], &write[1]); + __gem_busy(fd, obj[idx].handle, &read[1], &write[1]); igt_debug("After %d cycles: read[0]=%x read[1]=%x\n", - count, read[0], read[1]); - igt_require(count <= 1 << 10); - count <<= 1; + idx-1, read[0], read[1]); } while (read[0] == 0 || read[1] == 0); igt_assert_eq(write[0], ring); - igt_assert_eq(read[0], 1 << ring); + igt_assert_eq_u32(read[0], 1 << ring); igt_assert_eq(write[1], 0); - igt_assert_eq(read[1], 1 << ring); + igt_assert_eq_u32(read[1], 1 << ring); /* Calling busy in a loop should be enough to flush the rendering */ memset(&tv, 0, sizeof(tv)); - while (gem_busy(fd, obj[1].handle)) + while (gem_busy(fd, obj[idx].handle)) igt_assert(igt_seconds_elapsed(&tv) < 10); igt_assert(!gem_busy(fd, obj[0].handle)); - gem_close(fd, obj[1].handle); - gem_close(fd, obj[0].handle); + batch = gem_mmap__gtt(fd, obj[0].handle, 4096, PROT_READ); + for (i = 0; i < 1024; i++) + igt_assert_eq_u32(batch[i], i); + munmap(batch, 4096); + + for (i = 0; i <= idx; i++) { + struct drm_i915_gem_relocation_entry *r; + + r = (struct drm_i915_gem_relocation_entry *) + (uintptr_t)obj[i].relocs_ptr; + if (r != store) + free(r); + gem_close(fd, obj[i].handle); + } } static bool has_semaphores(int fd) |