[PATCH i-g-t 1/3] NORELOC - gem_exec_gttfill

Andrzej Turko andrzej.turko at linux.intel.com
Mon Apr 26 08:14:27 UTC 2021


From: Andrzej Turko <andrzej.turko at intel.com>

---
 tests/i915/gem_exec_gttfill.c | 72 ++++++++++++++++++++++++++++++-----
 1 file changed, 63 insertions(+), 9 deletions(-)

diff --git a/tests/i915/gem_exec_gttfill.c b/tests/i915/gem_exec_gttfill.c
index c0e27c9bb..73f89180e 100644
--- a/tests/i915/gem_exec_gttfill.c
+++ b/tests/i915/gem_exec_gttfill.c
@@ -28,6 +28,7 @@
 IGT_TEST_DESCRIPTION("Fill the GTT with batches.");
 
 #define BATCH_SIZE (4096<<10)
+#define BATCH_ALIGNMENT (1 << 12)
 
 struct batch {
 	uint32_t handle;
@@ -47,15 +48,21 @@ static void xchg_batch(void *array, unsigned int i, unsigned int j)
 static void submit(int fd, int gen,
 		   struct drm_i915_gem_execbuffer2 *eb,
 		   struct drm_i915_gem_relocation_entry *reloc,
-		   struct batch *batches, unsigned int count)
+		   struct batch *batches, unsigned int count,
+		   uint64_t ahnd, bool do_relocs)
 {
 	struct drm_i915_gem_exec_object2 obj;
 	uint32_t batch[16];
-	unsigned n;
+	uint64_t address, value;
+	unsigned n, j;
 
 	memset(&obj, 0, sizeof(obj));
-	obj.relocs_ptr = to_user_pointer(reloc);
-	obj.relocation_count = 2;
+	if (do_relocs) {
+		obj.relocs_ptr = to_user_pointer(reloc);
+		obj.relocation_count = 2;
+	} else {
+		obj.flags |= EXEC_OBJECT_PINNED;
+	}
 
 	memset(reloc, 0, 2*sizeof(*reloc));
 	reloc[0].offset = eb->batch_start_offset;
@@ -85,16 +92,44 @@ static void submit(int fd, int gen,
 	batch[++n] = 0; /* lower_32_bits(value) */
 	batch[++n] = 0; /* upper_32_bits(value) / nop */
 	batch[++n] = MI_BATCH_BUFFER_END;
-
 	eb->buffers_ptr = to_user_pointer(&obj);
+	j = 0;
 	for (unsigned i = 0; i < count; i++) {
 		obj.handle = batches[i].handle;
 		reloc[0].target_handle = obj.handle;
 		reloc[1].target_handle = obj.handle;
 
-		obj.offset = 0;
+		obj.offset = __intel_allocator_alloc(ahnd, obj.handle,
+						     BATCH_SIZE,
+						     BATCH_ALIGNMENT,
+						     ALLOC_STRATEGY_NONE);
+		for (; obj.offset == -1; j = ((++j) == count ? 0 : j)) {
+			if (i != j)
+				intel_allocator_free(ahnd, batches[j].handle);
+			obj.offset = __intel_allocator_alloc(ahnd, obj.handle,
+							     BATCH_SIZE,
+							     BATCH_ALIGNMENT,
+							     ALLOC_STRATEGY_NONE);
+		}
+
 		reloc[0].presumed_offset = obj.offset;
 		reloc[1].presumed_offset = obj.offset;
+		address = obj.offset + reloc[0].delta;
+		value = obj.offset + reloc[1].delta;
+
+		if (gen >= 8) {
+			batch[1] = address;
+			batch[2] = address >> 32;
+
+			batch[3] = value;
+			batch[4] = value >> 32;
+		} else if (gen >=4) {
+			batch[2] = address;
+			batch[3] = value;
+		} else {
+			batch[1] = address;
+			batch[3] = value;
+		}
 
 		memcpy(batches[i].ptr + eb->batch_start_offset,
 		       batch, sizeof(batch));
@@ -116,7 +151,8 @@ static void fillgtt(int fd, unsigned ring, int timeout)
 	struct batch *batches;
 	unsigned nengine;
 	unsigned count;
-	uint64_t size;
+	uint64_t size, ahnd;
+	bool do_relocs = !gem_uses_ppgtt(fd);
 
 	shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
 	igt_assert(shared != MAP_FAILED);
@@ -145,6 +181,12 @@ static void fillgtt(int fd, unsigned ring, int timeout)
 	count = size / BATCH_SIZE + 1;
 	igt_debug("Using %'d batches to fill %'llu aperture on %d engines\n",
 		  count, (long long)size, nengine);
+
+	intel_allocator_multiprocess_start();
+	/* Avoid allocating on the last page */
+	ahnd = intel_allocator_open_full(fd, 0, 0, size - 4096,
+					 INTEL_ALLOCATOR_SIMPLE,
+					 ALLOC_STRATEGY_NONE);
 	intel_require_memory(count, BATCH_SIZE, CHECK_RAM);
 	intel_detect_and_clear_missed_interrupts(fd);
 
@@ -165,7 +207,7 @@ static void fillgtt(int fd, unsigned ring, int timeout)
 	}
 
 	/* Flush all memory before we start the timer */
-	submit(fd, gen, &execbuf, reloc, batches, count);
+	submit(fd, gen, &execbuf, reloc, batches, count, ahnd, do_relocs);
 
 	igt_info("Setup %u batches in %.2fms\n",
 		 count, 1e-6 * igt_nsec_elapsed(&tv));
@@ -176,8 +218,14 @@ static void fillgtt(int fd, unsigned ring, int timeout)
 		igt_permute_array(batches, count, xchg_batch);
 		execbuf.batch_start_offset = child*64;
 		execbuf.flags |= engines[child];
+
+		/* We need to open the allocator again in the new process */
+		ahnd = intel_allocator_open_full(fd, 0, 0, size - 4096,
+						 INTEL_ALLOCATOR_SIMPLE,
+						 ALLOC_STRATEGY_NONE);
+
 		igt_until_timeout(timeout) {
-			submit(fd, gen, &execbuf, reloc, batches, count);
+			submit(fd, gen, &execbuf, reloc, batches, count, ahnd, do_relocs);
 			for (unsigned i = 0; i < count; i++) {
 				uint64_t offset, delta;
 
@@ -189,13 +237,18 @@ static void fillgtt(int fd, unsigned ring, int timeout)
 		}
 		shared[child] = cycles;
 		igt_info("engine[%d]: %llu cycles\n", child, (long long)cycles);
+		intel_allocator_close(ahnd);
 	}
 	igt_waitchildren();
 
+	intel_allocator_close(ahnd);
+	intel_allocator_multiprocess_stop();
+
 	for (unsigned i = 0; i < count; i++) {
 		munmap(batches[i].ptr, BATCH_SIZE);
 		gem_close(fd, batches[i].handle);
 	}
+	free(batches);
 
 	shared[nengine] = 0;
 	for (unsigned i = 0; i < nengine; i++)
@@ -216,6 +269,7 @@ igt_main
 		igt_fork_hang_detector(i915);
 	}
 
+
 	igt_subtest("basic") /* just enough to run a single pass */
 		fillgtt(i915, ALL_ENGINES, 1);
 
-- 
2.25.1



More information about the Intel-gfx-trybot mailing list