[igt-dev] [PATCH i-g-t 1/4] tests/i915/gem_exec_store: Support gens without relocations

Andrzej Turko andrzej.turko at linux.intel.com
Fri Jul 2 11:52:31 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 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



More information about the igt-dev mailing list