[igt-dev] [PATCH i-g-t v14 19/33] tests/gem_softpin: Verify allocator and execbuf pair work together

Zbigniew Kempczyński zbigniew.kempczynski at intel.com
Thu Jan 14 12:22:19 UTC 2021


Exercise objects offsets produced by the allocator for execbuf
are valid and no EINVAL/ENOSPC occurs. Check it works properly
also for multiprocess allocations/execbufs for same context.

For full-ppgtt we disable softpin to verify offsets produced
by the allocator are valid and kernel doesn't want to relocate them.

Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
---
 tests/i915/gem_softpin.c | 95 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/tests/i915/gem_softpin.c b/tests/i915/gem_softpin.c
index aba060a42..e1af29830 100644
--- a/tests/i915/gem_softpin.c
+++ b/tests/i915/gem_softpin.c
@@ -28,6 +28,7 @@
 
 #include "i915/gem.h"
 #include "igt.h"
+#include "intel_allocator.h"
 
 #define EXEC_OBJECT_PINNED	(1<<4)
 #define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3)
@@ -697,6 +698,91 @@ static void test_noreloc(int fd, enum sleep sleep, unsigned flags)
 		gem_close(fd, object[i].handle);
 }
 
+static void __exec_using_allocator(uint64_t ahnd, int fd, int num_obj,
+				   bool pinned)
+{
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 object[num_obj];
+	uint64_t stored_offsets[num_obj];
+	int i;
+
+	memset(object, 0, sizeof(object));
+	for (i = 0; i < num_obj; i++) {
+		uint32_t sz = (rand() % 15 + 1) * 4096;
+		if (i == num_obj - 1)
+			sz = 4096;
+		object[i].handle = gem_create(fd, sz);
+		object[i].offset = intel_allocator_alloc(ahnd, object[i].handle,
+							 sz, 0);
+		object[i].offset = gen8_canonical_addr(object[i].offset);
+		object[i].flags = pinned ? EXEC_OBJECT_PINNED : 0;
+		if (object[i].offset >= 1ull << 32)
+			object[i].flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
+	}
+	gem_write(fd, object[--i].handle, 0, &bbe, sizeof(bbe));
+
+	if (!pinned)
+		for (i = 0; i < num_obj; i++)
+			stored_offsets[i] = object[i].offset;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(object);
+	execbuf.buffer_count = num_obj;
+	gem_execbuf(fd, &execbuf);
+
+	for (i = 0; i < num_obj; i++) {
+		intel_allocator_free(ahnd, object[i].handle);
+		gem_close(fd, object[i].handle);
+	}
+
+	/* Check kernel will keep offsets even pinned is not set. */
+	if (!pinned)
+		for (i = 0; i < num_obj; i++)
+			igt_assert_eq_u64(stored_offsets[i], object[i].offset);
+}
+
+static void test_allocator_basic(int fd)
+{
+	const int num_obj = 257;
+	uint64_t ahnd;
+
+	ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE);
+	__exec_using_allocator(ahnd, fd, num_obj, true);
+	igt_assert(intel_allocator_close(ahnd) == true);
+}
+
+static void test_allocator_nopin(int fd)
+{
+	const int num_obj = 257;
+	uint64_t ahnd;
+
+	ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE);
+	__exec_using_allocator(ahnd, fd, num_obj, false);
+	igt_assert(intel_allocator_close(ahnd) == true);
+}
+
+static void test_allocator_fork(int fd)
+{
+	uint64_t ahnd;
+
+	intel_allocator_multiprocess_start();
+
+	igt_fork(child, 8) {
+		ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE);
+		igt_until_timeout(2)
+			__exec_using_allocator(ahnd, fd, 17, true);
+		intel_allocator_close(ahnd);
+	}
+
+	igt_waitchildren();
+
+	intel_allocator_multiprocess_stop();
+
+	ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_SIMPLE);
+	igt_assert(intel_allocator_close(ahnd) == true);
+}
+
 igt_main
 {
 	int fd = -1;
@@ -727,6 +813,9 @@ igt_main
 
 		igt_subtest("full")
 			test_full(fd);
+
+		igt_subtest("allocator-nopin")
+			test_allocator_nopin(fd);
 	}
 
 	igt_subtest("softpin")
@@ -754,6 +843,12 @@ igt_main
 	igt_subtest("evict-hang")
 		test_evict_hang(fd);
 
+	igt_subtest("allocator-basic")
+		test_allocator_basic(fd);
+
+	igt_subtest("allocator-fork")
+		test_allocator_fork(fd);
+
 	igt_fixture
 		close(fd);
 }
-- 
2.26.0



More information about the igt-dev mailing list