[PATCH i-g-t 13/15] i915/gem_create: Verify all regions return cleared objects

Matthew Auld matthew.auld at intel.com
Tue May 11 09:26:55 UTC 2021


From: Chris Wilson <chris.p.wilson at intel.com>

We do not tolerate leaking stale information in newly created objects, so
make sure the test covers all memory regions.

Signed-off-by: Chris Wilson <chris.p.wilson at intel.com>
Reviewed-by: Matthew Auld <matthew.auld at intel.com>
---
 tests/i915/gem_create.c | 128 ++++++++++++++++++++++++++++++++--------
 1 file changed, 105 insertions(+), 23 deletions(-)

diff --git a/tests/i915/gem_create.c b/tests/i915/gem_create.c
index 167d7d28..4ee13e64 100644
--- a/tests/i915/gem_create.c
+++ b/tests/i915/gem_create.c
@@ -65,6 +65,65 @@ IGT_TEST_DESCRIPTION("This is a test for the gem_create ioctl,"
 
 #define PAGE_SIZE 4096
 
+struct memory_region {
+	struct memory_region *next;
+	char *name;
+
+	struct drm_i915_gem_memory_class_instance ci;
+	uint64_t size;
+};
+
+static const char *
+region_repr(const struct drm_i915_gem_memory_class_instance *ci)
+{
+	switch (ci->memory_class) {
+	case I915_MEMORY_CLASS_SYSTEM:
+		return "smem";
+	case I915_MEMORY_CLASS_DEVICE:
+		return "lmem";
+	default:
+		return "unknown";
+	}
+}
+
+static struct memory_region *get_memory_regions(int i915)
+{
+	struct drm_i915_query_memory_regions *info;
+	struct memory_region *first = NULL;
+
+	info = gem_get_query_memory_regions(i915);
+	for (int i = 0; i < info->num_regions; i++) {
+		struct memory_region *r;
+
+		r = malloc(sizeof(*r));
+		igt_assert(r);
+
+		r->ci = info->regions[i].region;
+		r->size = info->regions[i].probed_size;
+		if (r->size == -1ull)
+			r->size = intel_get_avail_ram_mb() << 20;
+
+		asprintf(&r->name, "%s%d",
+			 region_repr(&r->ci), r->ci.memory_instance);
+
+		r->next = first;
+		first = r;
+	}
+	free(info);
+
+	return first;
+}
+
+static struct memory_region *next_memory_region(struct memory_region *r)
+{
+	struct memory_region *next = r->next;
+	free(r->name);
+	free(r);
+	return next;
+}
+
+#define for_each_memory_region(r__, fd__) for (r__ = get_memory_regions(fd__); r__; r__ = next_memory_region(r__))
+
 static int create_ioctl(int fd, struct drm_i915_gem_create *create)
 {
         int err = 0;
@@ -144,6 +203,7 @@ static uint64_t get_npages(_Atomic(uint64_t) *global, uint64_t npages)
 
 struct thread_clear {
 	_Atomic(uint64_t) max;
+	struct drm_i915_gem_memory_class_instance region;
 	int timeout;
 	int i915;
 };
@@ -151,38 +211,40 @@ struct thread_clear {
 static void *thread_clear(void *data)
 {
 	struct thread_clear *arg = data;
+	struct drm_i915_gem_create_ext_memory_regions p_region = {
+		.base = { .name = I915_GEM_CREATE_EXT_MEMORY_REGIONS },
+		.regions = to_user_pointer(&arg->region),
+		.num_regions = 1,
+	};
 	unsigned long checked = 0, total = 0;
 	enum { PRW, GTT, WC, WB, __LAST__ } mode = PRW;
 	int i915 = arg->i915;
 
 	igt_until_timeout(arg->timeout) {
-		struct drm_i915_gem_create create = {};
-		uint64_t npages;
+		uint64_t npages, size;
+		uint32_t handle;
 		void *ptr;
 
 		npages = random();
 		npages <<= 32;
 		npages |= random();
 		npages = get_npages(&arg->max, npages);
-		create.size = npages << 12;
+		size = npages << 12;
+		igt_assert_eq(__gem_create_ext(i915, &size, &handle, &p_region.base), 0);
 
-		create_ioctl(i915, &create);
 		switch (mode) {
 		case __LAST__:
 		case PRW:
 			ptr = NULL;
 			break;
 		case WB:
-			ptr = __gem_mmap__cpu(i915, create.handle,
-					      0, create.size, PROT_READ);
+			ptr = __gem_mmap__cpu(i915, handle, 0, size, PROT_READ);
 			break;
 		case WC:
-			ptr = __gem_mmap__wc(i915, create.handle,
-					     0, create.size, PROT_READ);
+			ptr = __gem_mmap__wc(i915, handle, 0, size, PROT_READ);
 			break;
 		case GTT:
-			ptr = __gem_mmap__gtt(i915, create.handle,
-					      create.size, PROT_READ);
+			ptr = __gem_mmap__gtt(i915, handle, size, PROT_READ);
 			break;
 		}
 		/* No set-domains as we are being as naughty as possible */
@@ -194,7 +256,7 @@ static void *thread_clear(void *data)
 			};
 
 			if (!ptr)
-				gem_read(i915, create.handle, x[0], x, sizeof(x));
+				gem_read(i915, handle, x[0], x, sizeof(x));
 			else if (page & 1)
 				igt_memcpy_from_wc(x, ptr + x[0], sizeof(x));
 			else
@@ -206,8 +268,8 @@ static void *thread_clear(void *data)
 			checked++;
 		}
 		if (ptr)
-			munmap(ptr, create.size);
-		gem_close(i915, create.handle);
+			munmap(ptr, size);
+		gem_close(i915, handle);
 
 		total += npages;
 		atomic_fetch_add(&arg->max, npages);
@@ -220,12 +282,13 @@ static void *thread_clear(void *data)
 	return (void *)(uintptr_t)checked;
 }
 
-static void always_clear(int i915, int timeout)
+static void always_clear(int i915, const struct memory_region *r, int timeout)
 {
 	struct thread_clear arg = {
 		.i915 = i915,
+		.region = r->ci,
+		.max = r->size >> 12, /* in pages */
 		.timeout = timeout,
-		.max = intel_get_avail_ram_mb() << (20 - 12), /* in pages */
 	};
 	const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
 	unsigned long checked;
@@ -243,8 +306,13 @@ static void always_clear(int i915, int timeout)
 	igt_info("Checked %'lu page allocations\n", checked);
 }
 
-static void busy_create(int i915, int timeout)
+static void busy_create(int i915, const struct memory_region *r, int timeout)
 {
+	struct drm_i915_gem_create_ext_memory_regions p_region = {
+		.base = { .name = I915_GEM_CREATE_EXT_MEMORY_REGIONS },
+		.regions = to_user_pointer(&r->ci),
+		.num_regions = 1,
+	};
 	struct intel_execution_engine2 *e;
 	igt_spin_t *spin[I915_EXEC_RING_MASK + 1];
 	unsigned long count = 0;
@@ -258,7 +326,7 @@ static void busy_create(int i915, int timeout)
 			uint32_t handle;
 			igt_spin_t *next;
 
-			handle = gem_create(i915, 4096);
+			handle = gem_create_ext(i915, 4096, &p_region.base);
 			next = igt_spin_new(i915,
 					    .engine = e->flags,
 					    .dependency = handle,
@@ -488,12 +556,6 @@ igt_main
 	igt_subtest("create-size-update")
 		size_update(fd);
 
-	igt_subtest("create-clear")
-		always_clear(fd, 30);
-
-	igt_subtest("busy-create")
-		busy_create(fd, 30);
-
 	igt_subtest("create-ext-placement-sanity-check")
 		create_ext_placement_sanity_check(fd);
 
@@ -503,4 +565,24 @@ igt_main
 	igt_subtest("create-ext-placement-all")
 		create_ext_placement_all(fd);
 
+	igt_subtest_with_dynamic("create-clear") {
+		struct memory_region *r;
+
+		for_each_memory_region(r, fd) {
+			igt_dynamic_f("%s", r->name)
+				always_clear(fd, r, 30);
+		}
+	}
+
+	igt_subtest_with_dynamic("busy-create") {
+		struct memory_region *r;
+
+		for_each_memory_region(r, fd) {
+			igt_dynamic_f("%s", r->name)
+				busy_create(fd, r, 30);
+		}
+	}
+
+	igt_fixture
+		close(fd);
 }
-- 
2.26.3



More information about the Intel-gfx-trybot mailing list