summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-04-15 10:39:36 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2016-04-15 10:58:14 +0100
commit4233b59608ce655298228b8b606aed0461c7af77 (patch)
treef0f9174a30a31fc8f84cb57f0f014f92388462c7
parent082fb26ce92442493543104d06af3a86382a4a8b (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.c121
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)