[igt-dev] [PATCH i-g-t, v2] tests/prime_mmap: Add support for local memory

Zbigniew Kempczyński zbigniew.kempczynski at intel.com
Thu Oct 14 12:31:23 UTC 2021


On Thu, Oct 14, 2021 at 04:39:22PM +0530, apoorva1.singh at intel.com wrote:
> From: Andrzej Turko <andrzej.turko at linux.intel.com>
> 
> Add support for local memory region (Device memory)
> 
> v2:
>   - Replace igt_skip_on() with igt_assert(), as with TTM
>     backend this test will not be able to run on discrete
>     currently.
>   - Fix minor line wrap changes.
> 
> Signed-off-by: Andrzej Turko <andrzej.turko at linux.intel.com>
> Signed-off-by: Apoorva Singh <apoorva1.singh at intel.com>
> Cc: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>
> Cc: Thomas Hellström <thomas.hellstrom at linux.intel.com>
> Cc: Melkaveri, Arjun <arjun.melkaveri at intel.com>
> ---
>  tests/prime_mmap.c | 254 +++++++++++++++++++++++++++------------------
>  1 file changed, 154 insertions(+), 100 deletions(-)
> 
> diff --git a/tests/prime_mmap.c b/tests/prime_mmap.c
> index a4e4b4b6..adbfaa22 100644
> --- a/tests/prime_mmap.c
> +++ b/tests/prime_mmap.c
> @@ -42,11 +42,14 @@
>  
>  #include "drm.h"
>  #include "drmtest.h"
> +#include "igt.h"
> +#include "igt_collection.h"
>  #include "i915_drm.h"
>  #include "i915/gem_create.h"
>  #include "i915/gem_mman.h"
>  #include "igt_debugfs.h"
>  #include "ioctl_wrappers.h"
> +#include "i915/intel_memory_region.h"
>  
>  #define BO_SIZE (16*1024)
>  
> @@ -68,119 +71,123 @@ fill_bo(uint32_t handle, size_t size)
>  }
>  
>  static void
> -fill_bo_cpu(char *ptr)
> +fill_bo_cpu(char *ptr, size_t size)
>  {
> -	memcpy(ptr, pattern, sizeof(pattern));
> +	off_t i;
> +	for (i = 0; i < size; i += sizeof(pattern))
> +	{
> +		memcpy(ptr + i, pattern, sizeof(pattern));
> +	}
>  }
>  
>  static void
> -test_correct(void)
> +test_correct(uint32_t region, int size)
>  {
>  	int dma_buf_fd;
>  	char *ptr1, *ptr2;
>  	uint32_t handle;
>  
> -	handle = gem_create(fd, BO_SIZE);
> -	fill_bo(handle, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	fill_bo(handle, size);
>  
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
>  	igt_assert(errno == 0);
>  
>  	/* Check correctness vs GEM_MMAP */
> -	ptr1 = gem_mmap__device_coherent(fd, handle, 0, BO_SIZE, PROT_READ);
> -	ptr2 = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	ptr1 = gem_mmap__device_coherent(fd, handle, 0, size, PROT_READ);
> +	ptr2 = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr1 != MAP_FAILED);
>  	igt_assert(ptr2 != MAP_FAILED);
> -	igt_assert(memcmp(ptr1, ptr2, BO_SIZE) == 0);
> +	igt_assert(memcmp(ptr1, ptr2, size) == 0);
>  
>  	/* Check pattern correctness */
>  	igt_assert(memcmp(ptr2, pattern, sizeof(pattern)) == 0);
>  
> -	munmap(ptr1, BO_SIZE);
> -	munmap(ptr2, BO_SIZE);
> +	munmap(ptr1, size);
> +	munmap(ptr2, size);
>  	close(dma_buf_fd);
>  	gem_close(fd, handle);
>  }
>  
>  static void
> -test_map_unmap(void)
> +test_map_unmap(uint32_t region, int size)
>  {
>  	int dma_buf_fd;
>  	char *ptr;
>  	uint32_t handle;
>  
> -	handle = gem_create(fd, BO_SIZE);
> -	fill_bo(handle, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	fill_bo(handle, size);
>  
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
>  	igt_assert(errno == 0);
>  
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr != MAP_FAILED);
>  	igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
>  
>  	/* Unmap and remap */
> -	munmap(ptr, BO_SIZE);
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	munmap(ptr, size);
> +	ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr != MAP_FAILED);
>  	igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
>  
> -	munmap(ptr, BO_SIZE);
> +	munmap(ptr, size);
>  	close(dma_buf_fd);
>  	gem_close(fd, handle);
>  }
>  
>  /* prime and then unprime and then prime again the same handle */
>  static void
> -test_reprime(void)
> +test_reprime(uint32_t region, int size)
>  {
>  	int dma_buf_fd;
>  	char *ptr;
>  	uint32_t handle;
>  
> -	handle = gem_create(fd, BO_SIZE);
> -	fill_bo(handle, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	fill_bo(handle, size);
>  
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
>  	igt_assert(errno == 0);
>  
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr != MAP_FAILED);
>  	igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
>  
>  	close (dma_buf_fd);
>  	igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
> -	munmap(ptr, BO_SIZE);
> +	munmap(ptr, size);
>  
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr != MAP_FAILED);
>  	igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
>  
> -	munmap(ptr, BO_SIZE);
> +	munmap(ptr, size);
>  	close(dma_buf_fd);
>  	gem_close(fd, handle);
>  }
>  
>  /* map from another process */
>  static void
> -test_forked(void)
> +test_forked(uint32_t region, int size)
>  {
>  	int dma_buf_fd;
>  	char *ptr;
>  	uint32_t handle;
>  
> -	handle = gem_create(fd, BO_SIZE);
> -	fill_bo(handle, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	fill_bo(handle, size);
>  
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
>  	igt_assert(errno == 0);
>  
>  	igt_fork(childno, 1) {
> -		ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +		ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  		igt_assert(ptr != MAP_FAILED);
>  		igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
> -		munmap(ptr, BO_SIZE);
> +		munmap(ptr, size);
>  		close(dma_buf_fd);
>  	}
>  	close(dma_buf_fd);
> @@ -190,13 +197,13 @@ test_forked(void)
>  
>  /* test simple CPU write */
>  static void
> -test_correct_cpu_write(void)
> +test_correct_cpu_write(uint32_t region, int size)
>  {
>  	int dma_buf_fd;
>  	char *ptr;
>  	uint32_t handle;
>  
> -	handle = gem_create(fd, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
>  
>  	dma_buf_fd = prime_handle_to_fd_for_mmap(fd, handle);
>  
> @@ -204,29 +211,29 @@ test_correct_cpu_write(void)
>  	igt_skip_on(errno == EINVAL);
>  
>  	/* Check correctness of map using write protection (PROT_WRITE) */
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf_fd, 0);
> +	ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr != MAP_FAILED);
>  
>  	/* Fill bo using CPU */
> -	fill_bo_cpu(ptr);
> +	fill_bo_cpu(ptr, BO_SIZE);
>  
>  	/* Check pattern correctness */
>  	igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
>  
> -	munmap(ptr, BO_SIZE);
> +	munmap(ptr, size);
>  	close(dma_buf_fd);
>  	gem_close(fd, handle);
>  }
>  
>  /* map from another process and then write using CPU */
>  static void
> -test_forked_cpu_write(void)
> +test_forked_cpu_write(uint32_t region, int size)
>  {
>  	int dma_buf_fd;
>  	char *ptr;
>  	uint32_t handle;
>  
> -	handle = gem_create(fd, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
>  
>  	dma_buf_fd = prime_handle_to_fd_for_mmap(fd, handle);
>  
> @@ -234,12 +241,12 @@ test_forked_cpu_write(void)
>  	igt_skip_on(errno == EINVAL);
>  
>  	igt_fork(childno, 1) {
> -		ptr = mmap(NULL, BO_SIZE, PROT_READ | PROT_WRITE , MAP_SHARED, dma_buf_fd, 0);
> +		ptr = mmap(NULL, size, PROT_READ | PROT_WRITE , MAP_SHARED, dma_buf_fd, 0);
>  		igt_assert(ptr != MAP_FAILED);
> -		fill_bo_cpu(ptr);
> +		fill_bo_cpu(ptr, BO_SIZE);
>  
>  		igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
> -		munmap(ptr, BO_SIZE);
> +		munmap(ptr, size);
>  		close(dma_buf_fd);
>  	}
>  	close(dma_buf_fd);
> @@ -248,45 +255,45 @@ test_forked_cpu_write(void)
>  }
>  
>  static void
> -test_refcounting(void)
> +test_refcounting(uint32_t region, int size)
>  {
>  	int dma_buf_fd;
>  	char *ptr;
>  	uint32_t handle;
>  
> -	handle = gem_create(fd, BO_SIZE);
> -	fill_bo(handle, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	fill_bo(handle, size);
>  
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
>  	igt_assert(errno == 0);
>  	/* Close gem object before mapping */
>  	gem_close(fd, handle);
>  
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr != MAP_FAILED);
>  	igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
> -	munmap(ptr, BO_SIZE);
> +	munmap(ptr, size);
>  	close (dma_buf_fd);
>  }
>  
>  /* dup before mmap */
>  static void
> -test_dup(void)
> +test_dup(uint32_t region, int size)
>  {
>  	int dma_buf_fd;
>  	char *ptr;
>  	uint32_t handle;
>  
> -	handle = gem_create(fd, BO_SIZE);
> -	fill_bo(handle, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	fill_bo(handle, size);
>  
>  	dma_buf_fd = dup(prime_handle_to_fd(fd, handle));
>  	igt_assert(errno == 0);
>  
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr != MAP_FAILED);
>  	igt_assert(memcmp(ptr, pattern, sizeof(pattern)) == 0);
> -	munmap(ptr, BO_SIZE);
> +	munmap(ptr, size);
>  	gem_close(fd, handle);
>  	close (dma_buf_fd);
>  }
> @@ -324,21 +331,21 @@ static bool has_userptr(void)
>  
>  /* test for mmap(dma_buf_export(userptr)) */
>  static void
> -test_userptr(void)
> +test_userptr(uint32_t region, int size)
>  {
>  	int ret, dma_buf_fd;
>  	void *ptr;
>  	uint32_t handle;
>  
> -	igt_require(has_userptr());
> -
>  	/* create userptr bo */
> -	ret = posix_memalign(&ptr, 4096, BO_SIZE);
> +	ret = posix_memalign(&ptr, 4096, size);
>  	igt_assert_eq(ret, 0);
>  
> -	/* we are not allowed to export unsynchronized userptr. Just create a normal
> -	 * one */

You've also unnecessary touched this line. With this minor nit fixed:

Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski at intel.com>

--
Zbigniew

> -	gem_userptr(fd, (uint32_t *)ptr, BO_SIZE, 0, 0, &handle);
> +	/*
> +	 * we are not allowed to export unsynchronized userptr. Just create a
> +	 * normal one
> +	 */
> +	gem_userptr(fd, (uint32_t *)ptr, size, 0, 0, &handle);
>  
>  	/* export userptr */
>  	ret = prime_handle_to_fd_no_assert(handle, DRM_CLOEXEC, &dma_buf_fd);
> @@ -352,7 +359,7 @@ test_userptr(void)
>  
>  	/* a userptr doesn't have the obj->base.filp, but can be exported via
>  	 * dma-buf, so make sure it fails here */
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr == MAP_FAILED && errno == ENODEV);
>  free_userptr:
>  	gem_close(fd, handle);
> @@ -360,7 +367,7 @@ free_userptr:
>  }
>  
>  static void
> -test_errors(void)
> +test_errors(uint32_t region, int size)
>  {
>  	int i, dma_buf_fd;
>  	char *ptr;
> @@ -369,48 +376,49 @@ test_errors(void)
>  	                       DRM_RDWR - 1, DRM_RDWR + 1};
>  
>  	/* Test for invalid flags */
> -	handle = gem_create(fd, BO_SIZE);
> -	for (i = 0; i < sizeof(invalid_flags) / sizeof(invalid_flags[0]); i++) {
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	for (i = 0; i < ARRAY_SIZE(invalid_flags); i++) {
>  		prime_handle_to_fd_no_assert(handle, invalid_flags[i], &dma_buf_fd);
>  		igt_assert_eq(errno, EINVAL);
>  		errno = 0;
>  	}
> +	gem_close(fd, handle);
>  
>  	/* Close gem object before priming */
> -	handle = gem_create(fd, BO_SIZE);
> -	fill_bo(handle, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	fill_bo(handle, size);
>  	gem_close(fd, handle);
>  	prime_handle_to_fd_no_assert(handle, DRM_CLOEXEC, &dma_buf_fd);
>  	igt_assert(dma_buf_fd == -1 && errno == ENOENT);
>  	errno = 0;
>  
>  	/* close fd before mapping */
> -	handle = gem_create(fd, BO_SIZE);
> -	fill_bo(handle, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	fill_bo(handle, size);
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
>  	igt_assert(errno == 0);
>  	close(dma_buf_fd);
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr == MAP_FAILED && errno == EBADF);
>  	errno = 0;
>  	gem_close(fd, handle);
>  
>  	/* Map too big */
> -	handle = gem_create(fd, BO_SIZE);
> -	fill_bo(handle, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
> +	fill_bo(handle, size);
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
>  	igt_assert(errno == 0);
> -	ptr = mmap(NULL, BO_SIZE * 2, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +	ptr = mmap(NULL, size * 2, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
>  	igt_assert(ptr == MAP_FAILED && errno == EINVAL);
>  	errno = 0;
>  	close(dma_buf_fd);
>  	gem_close(fd, handle);
>  
>  	/* Overlapping the end of the buffer */
> -	handle = gem_create(fd, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
>  	igt_assert(errno == 0);
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, BO_SIZE / 2);
> +	ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, dma_buf_fd, size / 2);
>  	igt_assert(ptr == MAP_FAILED && errno == EINVAL);
>  	errno = 0;
>  	close(dma_buf_fd);
> @@ -419,7 +427,7 @@ test_errors(void)
>  
>  /* Test for invalid flags on sync ioctl */
>  static void
> -test_invalid_sync_flags(void)
> +test_invalid_sync_flags(uint32_t region, int size)
>  {
>  	int i, dma_buf_fd;
>  	uint32_t handle;
> @@ -429,7 +437,7 @@ test_invalid_sync_flags(void)
>  	                       LOCAL_DMA_BUF_SYNC_RW + 1,
>  	                       LOCAL_DMA_BUF_SYNC_VALID_FLAGS_MASK + 1};
>  
> -	handle = gem_create(fd, BO_SIZE);
> +	handle = gem_create_in_memory_regions(fd, size, region);
>  	dma_buf_fd = prime_handle_to_fd(fd, handle);
>  	for (i = 0; i < sizeof(invalid_flags) / sizeof(invalid_flags[0]); i++) {
>  		memset(&sync, 0, sizeof(sync));
> @@ -442,7 +450,7 @@ test_invalid_sync_flags(void)
>  }
>  
>  static void
> -test_aperture_limit(void)
> +test_aperture_limit(uint32_t region, int size)
>  {
>  	int dma_buf_fd1, dma_buf_fd2;
>  	char *ptr1, *ptr2;
> @@ -452,23 +460,22 @@ test_aperture_limit(void)
>  	uint64_t size2 = (gem_mappable_aperture_size(fd) * 3) / 8;
>  
>  	handle1 = gem_create(fd, size1);
> -	fill_bo(handle1, BO_SIZE);
> -
> -	dma_buf_fd1 = prime_handle_to_fd(fd, handle1);
> +	dma_buf_fd1 = prime_handle_to_fd_for_mmap(fd, handle1);
>  	igt_assert(errno == 0);
> -	ptr1 = mmap(NULL, size1, PROT_READ, MAP_SHARED, dma_buf_fd1, 0);
> +	ptr1 = mmap(NULL, size1, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf_fd1, 0);
>  	igt_assert(ptr1 != MAP_FAILED);
> +	fill_bo_cpu(ptr1, size);
>  	igt_assert(memcmp(ptr1, pattern, sizeof(pattern)) == 0);
>  
>  	handle2 = gem_create(fd, size1);
> -	fill_bo(handle2, BO_SIZE);
> -	dma_buf_fd2 = prime_handle_to_fd(fd, handle2);
> +	dma_buf_fd2 = prime_handle_to_fd_for_mmap(fd, handle2);
>  	igt_assert(errno == 0);
> -	ptr2 = mmap(NULL, size2, PROT_READ, MAP_SHARED, dma_buf_fd2, 0);
> +	ptr2 = mmap(NULL, size2, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf_fd2, 0);
>  	igt_assert(ptr2 != MAP_FAILED);
> +	fill_bo_cpu(ptr2, size);
>  	igt_assert(memcmp(ptr2, pattern, sizeof(pattern)) == 0);
>  
> -	igt_assert(memcmp(ptr1, ptr2, BO_SIZE) == 0);
> +	igt_assert(memcmp(ptr1, ptr2, size) == 0);
>  
>  	munmap(ptr1, size1);
>  	munmap(ptr2, size2);
> @@ -479,29 +486,55 @@ test_aperture_limit(void)
>  }
>  
>  static int
> -check_for_dma_buf_mmap(void)
> +check_for_dma_buf_mmap(struct igt_collection *set)
>  {
> +	struct igt_collection *region;
> +	uint32_t reg;
>  	int dma_buf_fd;
>  	char *ptr;
>  	uint32_t handle;
>  	int ret = 1;
>  
> -	handle = gem_create(fd, BO_SIZE);
> -	dma_buf_fd = prime_handle_to_fd(fd, handle);
> -	ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> -	if (ptr != MAP_FAILED)
> -		ret = 0;
> -	munmap(ptr, BO_SIZE);
> -	gem_close(fd, handle);
> -	close(dma_buf_fd);
> +	for_each_combination(region, 1, set) {
> +		reg = igt_collection_get_value(region, 0);
> +		handle = gem_create_in_memory_regions(fd, BO_SIZE, reg);
> +
> +		dma_buf_fd = prime_handle_to_fd(fd, handle);
> +		ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
> +		if (ptr != MAP_FAILED)
> +			ret = 0;
> +		munmap(ptr, BO_SIZE);
> +		gem_close(fd, handle);
> +		close(dma_buf_fd);
> +	}
>  	return ret;
>  }
>  
> +#define SKIP_LMEM (1 << 0)
> +#define SKIP_USERPTR (1 << 1)
> +
> +/*
> + * true skips the test
> + */
> +static bool check_skip(uint32_t skip, uint32_t region)
> +{
> +	if ((skip & SKIP_LMEM) && IS_DEVICE_MEMORY_REGION(region))
> +		return true;
> +
> +	if (skip & SKIP_USERPTR)
> +		return !has_userptr();
> +
> +	return false;
> +}
> +
>  igt_main
>  {
> +	struct igt_collection *set, *regions;
> +	struct drm_i915_query_memory_regions *query_info;
>  	struct {
>  		const char *name;
> -		void (*fn)(void);
> +		void (*fn)(uint32_t, int);
> +		uint32_t skip;
>  	} tests[] = {
>  		{ "test_correct", test_correct },
>  		{ "test_map_unmap", test_map_unmap },
> @@ -511,25 +544,46 @@ igt_main
>  		{ "test_forked_cpu_write", test_forked_cpu_write },
>  		{ "test_refcounting", test_refcounting },
>  		{ "test_dup", test_dup },
> -		{ "test_userptr", test_userptr },
> +		{ "test_userptr", test_userptr, SKIP_LMEM | SKIP_USERPTR },
>  		{ "test_errors", test_errors },
>  		{ "test_invalid_sync_flags", test_invalid_sync_flags },
> -		{ "test_aperture_limit", test_aperture_limit },
> +		{ "test_aperture_limit", test_aperture_limit, SKIP_LMEM },
>  	};
> +	uint32_t region;
> +	char *ext;
> +	int size;
>  	int i;
>  
>  	igt_fixture {
>  		fd = drm_open_driver(DRIVER_INTEL);
> -		igt_skip_on((check_for_dma_buf_mmap() != 0));
> -		errno = 0;
> -	}
>  
> +		query_info = gem_get_query_memory_regions(fd);
> +		igt_assert(query_info);
>  
> -	for (i = 0; i < ARRAY_SIZE(tests); i++) {
> -		igt_subtest(tests[i].name)
> -			tests[i].fn();
> +		set = get_memory_region_set(query_info, I915_SYSTEM_MEMORY,
> +					    I915_DEVICE_MEMORY);
> +		igt_assert(check_for_dma_buf_mmap(set) == 0);
> +		errno = 0;
>  	}
>  
> -	igt_fixture
> +	for (i = 0; i < ARRAY_SIZE(tests); i++)
> +		igt_subtest_with_dynamic(tests[i].name) {
> +			for_each_combination(regions, 1, set) {
> +				region = igt_collection_get_value(regions, 0);
> +				size = gem_get_batch_size(fd, MEMORY_TYPE_FROM_REGION(region));
> +				size = max(size, BO_SIZE);
> +				if (check_skip(tests[i].skip, region))
> +					continue;
> +				ext = memregion_dynamic_subtest_name(regions);
> +				igt_dynamic_f("%s-%s", tests[i].name, ext)
> +					tests[i].fn(region, size);
> +				free(ext);
> +			}
> +		}
> +
> +	igt_fixture {
> +		free(query_info);
> +		igt_collection_destroy(set);
>  		close(fd);
> +	}
>  }
> -- 
> 2.25.1
> 


More information about the igt-dev mailing list