[igt-dev] [PATCH i-g-t 1/4] tests/i915/gem_exec_store: Support gens without relocations
From: Andrzej Turko <hidden>
Date: 2021-07-02 11:53:15
Subsystem:
the rest · Maintainer:
Linus Torvalds
With relocations disabled on newer generations tests must assign addresses to objects by themselves instead of relying on the driver. Signed-off-by: Andrzej Turko <redacted> Cc: Zbigniew Kempczyński <redacted> --- tests/i915/gem_exec_store.c | 194 +++++++++++++++++++++++++++--------- 1 file changed, 145 insertions(+), 49 deletions(-)
diff --git a/tests/i915/gem_exec_store.c b/tests/i915/gem_exec_store.c
index 2df0b27f6..a893482c4 100644
--- a/tests/i915/gem_exec_store.c
+++ b/tests/i915/gem_exec_store.c@@ -37,6 +37,9 @@ #define ENGINE_MASK (I915_EXEC_RING_MASK | I915_EXEC_BSD_MASK) +/* Without alignment detection we assume the worst-case scenario. */ +#define ALIGNMENT (1 << 21) + static void store_dword(int fd, const struct intel_execution_engine2 *e) { const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
@@ -44,7 +47,9 @@ static void store_dword(int fd, const struct intel_execution_engine2 *e) struct drm_i915_gem_relocation_entry reloc; struct drm_i915_gem_execbuffer2 execbuf; uint32_t batch[16]; + uint64_t ahnd; int i; + bool do_relocs = gem_has_relocations(fd); intel_detect_and_clear_missed_interrupts(fd); memset(&execbuf, 0, sizeof(execbuf));
@@ -54,43 +59,64 @@ static void store_dword(int fd, const struct intel_execution_engine2 *e) if (gen > 3 && gen < 6) execbuf.flags |= I915_EXEC_SECURE; + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE); + memset(obj, 0, sizeof(obj)); obj[0].handle = gem_create(fd, 4096); obj[1].handle = gem_create(fd, 4096); - memset(&reloc, 0, sizeof(reloc)); - reloc.target_handle = obj[0].handle; - reloc.presumed_offset = 0; - reloc.offset = sizeof(uint32_t); - reloc.delta = 0; - reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION; - reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION; - obj[1].relocs_ptr = to_user_pointer(&reloc); - obj[1].relocation_count = 1; + if (do_relocs) { + memset(&reloc, 0, sizeof(reloc)); + reloc.target_handle = obj[0].handle; + reloc.presumed_offset = obj[0].offset; + reloc.offset = sizeof(uint32_t); + reloc.delta = 0; + reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION; + reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION; + obj[1].relocs_ptr = to_user_pointer(&reloc); + obj[1].relocation_count = 1; + } else { + obj[0].offset = intel_allocator_alloc(ahnd, obj[0].handle, + 4096, ALIGNMENT); + obj[0].offset = CANONICAL(obj[0].offset); + obj[0].flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS | + EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE; + + obj[1].offset = intel_allocator_alloc(ahnd, obj[1].handle, + 4096, ALIGNMENT); + obj[1].offset = CANONICAL(obj[1].offset); + obj[1].flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS | + EXEC_OBJECT_PINNED; + } i = 0; batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0); if (gen >= 8) { - batch[++i] = 0; - batch[++i] = 0; + batch[++i] = obj[0].offset; + batch[++i] = obj[0].offset >> 32; } else if (gen >= 4) { batch[++i] = 0; - batch[++i] = 0; + batch[++i] = obj[0].offset; reloc.offset += sizeof(uint32_t); } else { batch[i]--; - batch[++i] = 0; + batch[++i] = obj[0].offset; } batch[++i] = 0xc0ffee; batch[++i] = MI_BATCH_BUFFER_END; gem_write(fd, obj[1].handle, 0, batch, sizeof(batch)); + gem_execbuf(fd, &execbuf); + gem_close(fd, obj[1].handle); + intel_allocator_free(ahnd, obj[1].handle); gem_read(fd, obj[0].handle, 0, batch, sizeof(batch)); gem_close(fd, obj[0].handle); + intel_allocator_free(ahnd, obj[0].handle); igt_assert_eq(*batch, 0xc0ffee); igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0); + intel_allocator_close(ahnd); } #define PAGES 1
@@ -103,7 +129,9 @@ static void store_cachelines(int fd, const struct intel_execution_engine2 *e, struct drm_i915_gem_execbuffer2 execbuf; #define NCACHELINES (4096/64) uint32_t *batch; + uint64_t ahnd, reloc_value; int i; + bool do_relocs = gem_has_relocations(fd); reloc = calloc(NCACHELINES, sizeof(*reloc)); igt_assert(reloc);
@@ -115,36 +143,58 @@ static void store_cachelines(int fd, const struct intel_execution_engine2 *e, if (gen > 3 && gen < 6) execbuf.flags |= I915_EXEC_SECURE; + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE); obj = calloc(execbuf.buffer_count, sizeof(*obj)); igt_assert(obj); - for (i = 0; i < execbuf.buffer_count; i++) + for (i = 0; i < execbuf.buffer_count; i++) { obj[i].handle = gem_create(fd, 4096); - obj[i-1].relocs_ptr = to_user_pointer(reloc); - obj[i-1].relocation_count = NCACHELINES; + + if (!do_relocs) { + obj[i].offset = intel_allocator_alloc(ahnd, obj[i].handle, + 4096, ALIGNMENT); + obj[i].offset = CANONICAL(obj[i].offset); + obj[i].flags = EXEC_OBJECT_SUPPORTS_48B_ADDRESS | + EXEC_OBJECT_PINNED; + if (i + 1 < execbuf.buffer_count) + obj[i].flags |= EXEC_OBJECT_WRITE; + } + } + if (do_relocs) { + obj[i-1].relocs_ptr = to_user_pointer(reloc); + obj[i-1].relocation_count = NCACHELINES; + } execbuf.buffers_ptr = to_user_pointer(obj); batch = gem_mmap__cpu(fd, obj[i-1].handle, 0, 4096, PROT_WRITE); i = 0; for (unsigned n = 0; n < NCACHELINES; n++) { + reloc[n].target_handle = obj[n % (execbuf.buffer_count-1)].handle; - reloc[n].presumed_offset = -1; - reloc[n].offset = (i + 1)*sizeof(uint32_t); reloc[n].delta = 4 * (n * 16 + n % 16); - reloc[n].read_domains = I915_GEM_DOMAIN_INSTRUCTION; - reloc[n].write_domain = I915_GEM_DOMAIN_INSTRUCTION; + + if (do_relocs) { + reloc[n].presumed_offset = -1; + reloc[n].offset = (i + 1)*sizeof(uint32_t); + reloc[n].read_domains = I915_GEM_DOMAIN_INSTRUCTION; + reloc[n].write_domain = I915_GEM_DOMAIN_INSTRUCTION; + reloc_value = 0; + } else { + reloc_value = obj[n % (execbuf.buffer_count-1)].offset + + reloc[n].delta; + } batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0); if (gen >= 8) { - batch[++i] = 0; - batch[++i] = 0; + batch[++i] = reloc_value; + batch[++i] = reloc_value >> 32; } else if (gen >= 4) { batch[++i] = 0; - batch[++i] = 0; + batch[++i] = reloc_value; reloc[n].offset += sizeof(uint32_t); } else { batch[i]--; - batch[++i] = 0; + batch[++i] = reloc_value; } batch[++i] = n | ~n << 16; i++;
@@ -164,11 +214,14 @@ static void store_cachelines(int fd, const struct intel_execution_engine2 *e, } free(reloc); - for (unsigned n = 0; n < execbuf.buffer_count; n++) + for (unsigned n = 0; n < execbuf.buffer_count; n++) { gem_close(fd, obj[n].handle); + intel_allocator_free(ahnd, obj[n].handle); + } free(obj); igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0); + intel_allocator_close(ahnd); } static void store_all(int fd)
@@ -180,10 +233,11 @@ static void store_all(int fd) struct drm_i915_gem_execbuffer2 execbuf; unsigned *engines, *permuted; uint32_t batch[16]; - uint64_t offset; + uint64_t offset, ahnd, reloc_value; unsigned nengine; - int value; + int value, address; int i, j; + bool do_relocs = gem_has_relocations(fd); nengine = 0; __for_each_physical_engine(fd, engine) {
@@ -208,24 +262,43 @@ static void store_all(int fd) if (gen < 6) execbuf.flags |= I915_EXEC_SECURE; + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE); + memset(obj, 0, sizeof(obj)); obj[0].handle = gem_create(fd, nengine*sizeof(uint32_t)); obj[1].handle = gem_create(fd, 2*nengine*sizeof(batch)); - obj[1].relocation_count = 1; + + if (do_relocs) { + obj[1].relocation_count = 1; + } else { + obj[0].offset = intel_allocator_alloc(ahnd, obj[0].handle, + nengine*sizeof(uint32_t), + ALIGNMENT); + obj[0].offset = CANONICAL(obj[0].offset); + obj[0].flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS | + EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE; + + obj[1].offset = intel_allocator_alloc(ahnd, obj[1].handle, + 2*nengine*sizeof(batch), + ALIGNMENT); + obj[1].offset = CANONICAL(obj[1].offset); + obj[1].flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS | + EXEC_OBJECT_PINNED; + } offset = sizeof(uint32_t); i = 0; batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0); if (gen >= 8) { - batch[++i] = 0; + batch[address = ++i] = 0; batch[++i] = 0; } else if (gen >= 4) { batch[++i] = 0; - batch[++i] = 0; + batch[address = ++i] = 0; offset += sizeof(uint32_t); } else { batch[i]--; - batch[++i] = 0; + batch[address = ++i] = 0; } batch[value = ++i] = 0xc0ffee; batch[++i] = MI_BATCH_BUFFER_END;
@@ -240,30 +313,45 @@ static void store_all(int fd) execbuf.flags |= engine->flags; j = 2*nengine; - reloc[j].target_handle = obj[0].handle; - reloc[j].presumed_offset = ~0; - reloc[j].offset = j*sizeof(batch) + offset; - reloc[j].delta = nengine*sizeof(uint32_t); - reloc[j].read_domains = I915_GEM_DOMAIN_INSTRUCTION; - reloc[j].write_domain = I915_GEM_DOMAIN_INSTRUCTION; - obj[1].relocs_ptr = to_user_pointer(&reloc[j]); - + if (do_relocs) { + reloc[j].target_handle = obj[0].handle; + reloc[j].presumed_offset = ~0; + reloc[j].offset = j*sizeof(batch) + offset; + reloc[j].delta = nengine*sizeof(uint32_t); + reloc[j].read_domains = I915_GEM_DOMAIN_INSTRUCTION; + reloc[j].write_domain = I915_GEM_DOMAIN_INSTRUCTION; + obj[1].relocs_ptr = to_user_pointer(&reloc[j]); + } else { + reloc_value = obj[0].offset + nengine*sizeof(uint32_t); + /* If there is no relocation support, we assume gen >= 8. */ + batch[address] = reloc_value; + batch[address + 1] = reloc_value >> 32; + } batch[value] = 0xdeadbeef; + gem_write(fd, obj[1].handle, j*sizeof(batch), batch, sizeof(batch)); execbuf.batch_start_offset = j*sizeof(batch); gem_execbuf(fd, &execbuf); j = 2*nengine + 1; - reloc[j].target_handle = obj[0].handle; - reloc[j].presumed_offset = ~0; - reloc[j].offset = j*sizeof(batch) + offset; - reloc[j].delta = nengine*sizeof(uint32_t); - reloc[j].read_domains = I915_GEM_DOMAIN_INSTRUCTION; - reloc[j].write_domain = I915_GEM_DOMAIN_INSTRUCTION; - obj[1].relocs_ptr = to_user_pointer(&reloc[j]); - + if (do_relocs) { + reloc[j].target_handle = obj[0].handle; + reloc[j].presumed_offset = ~0; + reloc[j].offset = j*sizeof(batch) + offset; + reloc[j].delta = nengine*sizeof(uint32_t); + reloc[j].read_domains = I915_GEM_DOMAIN_INSTRUCTION; + reloc[j].write_domain = I915_GEM_DOMAIN_INSTRUCTION; + obj[1].relocs_ptr = to_user_pointer(&reloc[j]); + } else { + reloc_value = obj[0].offset + nengine*sizeof(uint32_t); + batch[address] = reloc_value; + /* If there is no relocation support, we assume gen >= 8. */ + batch[address] = reloc_value; + batch[address + 1] = reloc_value >> 32; + } batch[value] = nengine; + gem_write(fd, obj[1].handle, j*sizeof(batch), batch, sizeof(batch)); execbuf.batch_start_offset = j*sizeof(batch);
@@ -274,30 +362,38 @@ static void store_all(int fd) gem_sync(fd, obj[1].handle); for (i = 0; i < nengine; i++) { - obj[1].relocs_ptr = to_user_pointer(&reloc[2*i]); execbuf.batch_start_offset = 2*i*sizeof(batch); memcpy(permuted, engines, nengine*sizeof(engines[0])); igt_permute_array(permuted, nengine, igt_exchange_int); + if (do_relocs) + obj[1].relocs_ptr = to_user_pointer(&reloc[2*i]); + for (j = 0; j < nengine; j++) { execbuf.flags &= ~ENGINE_MASK; execbuf.flags |= permuted[j]; gem_execbuf(fd, &execbuf); } - obj[1].relocs_ptr = to_user_pointer(&reloc[2*i+1]); + execbuf.batch_start_offset = (2*i+1)*sizeof(batch); execbuf.flags &= ~ENGINE_MASK; execbuf.flags |= engines[i]; + if (do_relocs) + obj[1].relocs_ptr = to_user_pointer(&reloc[2*i+1]); + gem_execbuf(fd, &execbuf); } gem_close(fd, obj[1].handle); + intel_allocator_free(ahnd, obj[1].handle); gem_read(fd, obj[0].handle, 0, engines, nengine*sizeof(engines[0])); gem_close(fd, obj[0].handle); + intel_allocator_free(ahnd, obj[0].handle); for (i = 0; i < nengine; i++) igt_assert_eq_u32(engines[i], i); igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0); + intel_allocator_close(ahnd); free(permuted); free(engines); free(reloc);
--
2.25.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev