[igt-dev] [PATCH i-g-t 2/2] tests/i915/gem_exec_store: Support gens without relocations
Andrzej Turko
andrzej.turko at linux.intel.com
Wed May 12 05:40:10 UTC 2021
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 <andrzej.turko at linux.intel.com>
Cc: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
---
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 771ee1690..677cf8b9f 100644
--- a/tests/i915/gem_exec_store.c
+++ b/tests/i915/gem_exec_store.c
@@ -36,6 +36,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));
@@ -43,7 +46,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));
@@ -53,43 +58,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
@@ -102,7 +128,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);
@@ -114,36 +142,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++;
@@ -163,11 +213,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)
@@ -179,10 +232,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) {
@@ -207,24 +261,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;
@@ -239,30 +312,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);
@@ -273,30 +361,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
More information about the igt-dev
mailing list