[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 12:33:16 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