@@ -73,18 +73,30 @@
static uint32_t userptr_flags = LOCAL_I915_USERPTR_UNSYNCHRONIZED;
-static bool can_gtt_mmap;
+static bool *can_mmap;
#define WIDTH 512
#define HEIGHT 512
static uint32_t linear[WIDTH*HEIGHT];
-static bool has_gtt_mmap(int i915)
+static bool has_mmap(int i915, const struct mmap_offset *t)
{
void *ptr, *map = NULL;
uint32_t handle;
+ handle = gem_create(i915, PAGE_SIZE);
+ map = __gem_mmap_offset(i915, handle, 0, PAGE_SIZE, PROT_WRITE,
+ t->type);
+ gem_close(i915, handle);
+ if (map) {
+ munmap(map, PAGE_SIZE);
+ } else {
+ igt_debug("no HW / kernel support for mmap-offset(%s)\n",
+ t->name);
+ return false;
+ }
+
igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0);
if (__gem_userptr(i915, ptr, 4096, 0,
@@ -92,9 +104,12 @@ static bool has_gtt_mmap(int i915)
goto out_ptr;
igt_assert(handle != 0);
- map = __gem_mmap__gtt(i915, handle, 4096, PROT_WRITE);
+ map = __gem_mmap_offset(i915, handle, 0, 4096, PROT_WRITE, t->type);
if (map)
munmap(map, 4096);
+ else if (errno == ENODEV)
+ igt_debug("mmap-offset(%s) banned, lockdep loop prevention\n",
+ t->name);
gem_close(i915, handle);
out_ptr:
@@ -641,20 +656,25 @@ static int test_invalid_gtt_mapping(int fd)
return 0;
}
-#define PE_GTT_MAP 0x1
-#define PE_BUSY 0x2
-static void test_process_exit(int fd, int flags)
+#define PE_BUSY 0x1
+static void test_process_exit(int fd, const struct mmap_offset *mmo, int flags)
{
- if (flags & PE_GTT_MAP)
- igt_require(can_gtt_mmap);
+ if (mmo)
+ igt_require_f(can_mmap[mmo->type],
+ "HW & kernel support for LLC and mmap-offset(%s) over userptr\n",
+ mmo->name);
igt_fork(child, 1) {
uint32_t handle;
handle = create_userptr_bo(fd, sizeof(linear));
- if (flags & PE_GTT_MAP) {
- uint32_t *ptr = __gem_mmap__gtt(fd, handle, sizeof(linear), PROT_READ | PROT_WRITE);
+ if (mmo) {
+ uint32_t *ptr;
+
+ ptr = __gem_mmap_offset(fd, handle, 0, sizeof(linear),
+ PROT_READ | PROT_WRITE,
+ mmo->type);
if (ptr)
*ptr = 0;
}
@@ -878,13 +898,14 @@ static void (* volatile orig_sigbus)(int sig, siginfo_t *info, void *param);
static volatile unsigned long sigbus_start;
static volatile long sigbus_cnt = -1;
-static void *umap(int fd, uint32_t handle)
+static void *umap(int fd, uint32_t handle, const struct mmap_offset *mmo)
{
void *ptr;
- if (can_gtt_mmap) {
- ptr = gem_mmap__gtt(fd, handle, sizeof(linear),
- PROT_READ | PROT_WRITE);
+ if (mmo) {
+ ptr = __gem_mmap_offset(fd, handle, 0, sizeof(linear),
+ PROT_READ | PROT_WRITE, mmo->type);
+ igt_assert(ptr);
} else {
uint32_t tmp = gem_create(fd, sizeof(linear));
igt_assert_eq(copy(fd, tmp, handle), 0);
@@ -896,16 +917,17 @@ static void *umap(int fd, uint32_t handle)
}
static void
-check_bo(int fd1, uint32_t handle1, int is_userptr, int fd2, uint32_t handle2)
+check_bo(int fd1, uint32_t handle1, int is_userptr, int fd2, uint32_t handle2,
+ const struct mmap_offset *mmo)
{
unsigned char *ptr1, *ptr2;
unsigned long size = sizeof(linear);
- ptr2 = umap(fd2, handle2);
+ ptr2 = umap(fd2, handle2, mmo);
if (is_userptr)
ptr1 = is_userptr > 0 ? get_handle_ptr(handle1) : ptr2;
else
- ptr1 = umap(fd1, handle1);
+ ptr1 = umap(fd1, handle1, mmo);
igt_assert(ptr1);
igt_assert(ptr2);
@@ -913,7 +935,7 @@ check_bo(int fd1, uint32_t handle1, int is_userptr, int fd2, uint32_t handle2)
sigbus_start = (unsigned long)ptr2;
igt_assert(memcmp(ptr1, ptr2, sizeof(linear)) == 0);
- if (can_gtt_mmap) {
+ if (mmo) {
counter++;
memset(ptr1, counter, size);
memset(ptr2, counter, size);
@@ -971,9 +993,17 @@ static int test_dmabuf(void)
uint32_t handle, handle_import;
int dma_buf_fd = -1;
int ret;
+ const struct mmap_offset *mmo = NULL;
fd1 = drm_open_driver(DRIVER_INTEL);
+ for_each_mmap_offset_type(fd1, t)
+ if (can_mmap[t->type]) {
+ igt_debug("using mmap-offset(%s)\n", t->name);
+ mmo = t;
+ break;
+ }
+
handle = create_userptr_bo(fd1, sizeof(linear));
memset(get_handle_ptr(handle), counter, sizeof(linear));
@@ -990,17 +1020,17 @@ static int test_dmabuf(void)
fd2 = drm_open_driver(DRIVER_INTEL);
handle_import = prime_fd_to_handle(fd2, dma_buf_fd);
- check_bo(fd1, handle, 1, fd2, handle_import);
+ check_bo(fd1, handle, 1, fd2, handle_import, mmo);
/* close dma_buf, check whether nothing disappears. */
close(dma_buf_fd);
- check_bo(fd1, handle, 1, fd2, handle_import);
+ check_bo(fd1, handle, 1, fd2, handle_import, mmo);
/* destroy userptr object and expect SIGBUS */
free_userptr_bo(fd1, handle);
close(fd1);
- if (can_gtt_mmap) {
+ if (mmo) {
struct sigaction sigact, orig_sigact;
memset(&sigact, 0, sizeof(sigact));
@@ -1012,7 +1042,7 @@ static int test_dmabuf(void)
orig_sigbus = orig_sigact.sa_sigaction;
sigbus_cnt = 0;
- check_bo(fd2, handle_import, -1, fd2, handle_import);
+ check_bo(fd2, handle_import, -1, fd2, handle_import, mmo);
igt_assert(sigbus_cnt > 0);
ret = sigaction(SIGBUS, &orig_sigact, NULL);
@@ -1975,12 +2005,23 @@ igt_main_args("c:", NULL, help_str, opt_handler, NULL)
int size = sizeof(linear);
igt_fixture {
+ unsigned int mmo_max = 0;
+
fd = drm_open_driver(DRIVER_INTEL);
igt_assert(fd >= 0);
igt_require_gem(fd);
gem_require_blitter(fd);
- can_gtt_mmap = has_gtt_mmap(fd) && gem_has_llc(fd);
+ for_each_mmap_offset_type(fd, t)
+ if (t->type >= mmo_max)
+ mmo_max = t->type + 1;
+ igt_assert(mmo_max);
+
+ can_mmap = calloc(mmo_max, sizeof(*can_mmap));
+ igt_assert(can_mmap);
+
+ for_each_mmap_offset_type(fd, t)
+ can_mmap[t->type] = has_mmap(fd, t) && gem_has_llc(fd);
size = sizeof(linear);
@@ -2135,16 +2176,22 @@ igt_main_args("c:", NULL, help_str, opt_handler, NULL)
}
igt_subtest("process-exit")
- test_process_exit(fd, 0);
+ test_process_exit(fd, NULL, 0);
- igt_subtest("process-exit-gtt")
- test_process_exit(fd, PE_GTT_MAP);
+ igt_describe("Test process exit with userptr object mmapped via mmap-offset");
+ igt_subtest_with_dynamic("process-exit-mmap")
+ for_each_mmap_offset_type(fd, t)
+ igt_dynamic(t->name)
+ test_process_exit(fd, t, 0);
igt_subtest("process-exit-busy")
- test_process_exit(fd, PE_BUSY);
+ test_process_exit(fd, NULL, PE_BUSY);
- igt_subtest("process-exit-gtt-busy")
- test_process_exit(fd, PE_GTT_MAP | PE_BUSY);
+ igt_describe("Test process exit with busy userptr object mmapped via mmap-offset");
+ igt_subtest_with_dynamic("process-exit-mmap-busy")
+ for_each_mmap_offset_type(fd, t)
+ igt_dynamic(t->name)
+ test_process_exit(fd, t, PE_BUSY);
igt_subtest("create-destroy-sync")
test_create_destroy(fd, 5);
@@ -2244,4 +2291,7 @@ igt_main_args("c:", NULL, help_str, opt_handler, NULL)
igt_subtest("access-control")
test_access_control(fd);
+
+ igt_fixture
+ free(can_mmap);
}
Extend initial check for support of MMAP_GTT mapping to userptr with equivalent checks for each MMAP_OFFSET mapping type supported by i915 driver. Based on that, extend coverage of process-exit-gtt* subtests over non-GTT mapping types. In case of dmabuf-* subtests, use first supported mapping type if there are any. Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com> --- tests/i915/gem_userptr_blits.c | 108 ++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 29 deletions(-)