From e1f663b543e89a58746b0d0bebb7bab30d325e1c Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Wed, 12 Aug 2015 15:57:12 -0300 Subject: lib: Add gem_userptr and __gem_userptr helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch moves userptr definitions and helpers implementation that were locally in gem_userptr_benchmark and gem_userptr_blits to the library, so other tests can make use of them as well. There's no functional changes. v2: added __ function to differentiate when errors want to be handled back in the caller; bring gem_userptr_sync back to gem_userptr_blits; added gtkdoc. v8: remove local_i915_gem_userptr from gem_concurrent_all.c to use the global helpers instead. Signed-off-by: Tiago Vignatti Reviewed-by: Stéphane Marchesin Signed-off-by: Daniel Vetter --- benchmarks/gem_userptr_benchmark.c | 55 +++---------------- lib/ioctl_wrappers.c | 41 ++++++++++++++ lib/ioctl_wrappers.h | 13 +++++ tests/gem_concurrent_all.c | 9 ---- tests/gem_userptr_blits.c | 106 ++++++++++--------------------------- 5 files changed, 87 insertions(+), 137 deletions(-) diff --git a/benchmarks/gem_userptr_benchmark.c b/benchmarks/gem_userptr_benchmark.c index 1eae7ffd..f7716dfa 100644 --- a/benchmarks/gem_userptr_benchmark.c +++ b/benchmarks/gem_userptr_benchmark.c @@ -58,17 +58,6 @@ #define PAGE_SIZE 4096 #endif -#define LOCAL_I915_GEM_USERPTR 0x33 -#define LOCAL_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_USERPTR, struct local_i915_gem_userptr) -struct local_i915_gem_userptr { - uint64_t user_ptr; - uint64_t user_size; - uint32_t flags; -#define LOCAL_I915_USERPTR_READ_ONLY (1<<0) -#define LOCAL_I915_USERPTR_UNSYNCHRONIZED (1<<31) - uint32_t handle; -}; - static uint32_t userptr_flags = LOCAL_I915_USERPTR_UNSYNCHRONIZED; #define BO_SIZE (65536) @@ -83,30 +72,6 @@ static void gem_userptr_test_synchronized(void) userptr_flags = 0; } -static int gem_userptr(int fd, void *ptr, int size, int read_only, uint32_t *handle) -{ - struct local_i915_gem_userptr userptr; - int ret; - - userptr.user_ptr = (uintptr_t)ptr; - userptr.user_size = size; - userptr.flags = userptr_flags; - if (read_only) - userptr.flags |= LOCAL_I915_USERPTR_READ_ONLY; - - ret = drmIoctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &userptr); - if (ret) - ret = errno; - igt_skip_on_f(ret == ENODEV && - (userptr_flags & LOCAL_I915_USERPTR_UNSYNCHRONIZED) == 0 && - !read_only, - "Skipping, synchronized mappings with no kernel CONFIG_MMU_NOTIFIER?"); - if (ret == 0) - *handle = userptr.handle; - - return ret; -} - static void **handle_ptr_map; static unsigned int num_handle_ptr_map; @@ -144,8 +109,7 @@ static uint32_t create_userptr_bo(int fd, int size) ret = posix_memalign(&ptr, PAGE_SIZE, size); igt_assert(ret == 0); - ret = gem_userptr(fd, (uint32_t *)ptr, size, 0, &handle); - igt_assert(ret == 0); + gem_userptr(fd, (uint32_t *)ptr, size, 0, userptr_flags, &handle); add_handle_ptr(handle, ptr); return handle; @@ -167,7 +131,7 @@ static int has_userptr(int fd) assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); oldflags = userptr_flags; gem_userptr_test_unsynchronized(); - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle); + ret = __gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle); userptr_flags = oldflags; if (ret != 0) { free(ptr); @@ -379,9 +343,7 @@ static void test_impact_overlap(int fd, const char *prefix) for (i = 0, p = block; i < nr_bos[subtest]; i++, p += PAGE_SIZE) - ret = gem_userptr(fd, (uint32_t *)p, BO_SIZE, 0, - &handles[i]); - igt_assert(ret == 0); + gem_userptr(fd, (uint32_t *)p, BO_SIZE, 0, userptr_flags, &handles[i]); } if (nr_bos[subtest] > 0) @@ -427,7 +389,6 @@ static void test_single(int fd) char *ptr, *bo_ptr; uint32_t handle = 0; unsigned long iter = 0; - int ret; unsigned long map_size = BO_SIZE + PAGE_SIZE - 1; ptr = mmap(NULL, map_size, PROT_READ | PROT_WRITE, @@ -439,8 +400,7 @@ static void test_single(int fd) start_test(test_duration_sec); while (run_test) { - ret = gem_userptr(fd, bo_ptr, BO_SIZE, 0, &handle); - assert(ret == 0); + gem_userptr(fd, bo_ptr, BO_SIZE, 0, userptr_flags, &handle); gem_close(fd, handle); iter++; } @@ -456,7 +416,6 @@ static void test_multiple(int fd, unsigned int batch, int random) uint32_t handles[10000]; int map[10000]; unsigned long iter = 0; - int ret; int i; unsigned long map_size = batch * BO_SIZE + PAGE_SIZE - 1; @@ -478,10 +437,8 @@ static void test_multiple(int fd, unsigned int batch, int random) if (random) igt_permute_array(map, batch, igt_exchange_int); for (i = 0; i < batch; i++) { - ret = gem_userptr(fd, bo_ptr + map[i] * BO_SIZE, - BO_SIZE, - 0, &handles[i]); - assert(ret == 0); + gem_userptr(fd, bo_ptr + map[i] * BO_SIZE, BO_SIZE, + 0, userptr_flags, &handles[i]); } if (random) igt_permute_array(map, batch, igt_exchange_int); diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c index f371bf07..7cc24ba3 100644 --- a/lib/ioctl_wrappers.c +++ b/lib/ioctl_wrappers.c @@ -896,6 +896,47 @@ void gem_context_require_ban_period(int fd) igt_require(has_ban_period); } +int __gem_userptr(int fd, void *ptr, int size, int read_only, uint32_t flags, uint32_t *handle) +{ + struct local_i915_gem_userptr userptr; + int ret; + + memset(&userptr, 0, sizeof(userptr)); + userptr.user_ptr = (uintptr_t)ptr; + userptr.user_size = size; + userptr.flags = flags; + if (read_only) + userptr.flags |= LOCAL_I915_USERPTR_READ_ONLY; + + ret = drmIoctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &userptr); + if (ret) + ret = errno; + igt_skip_on_f(ret == ENODEV && + (flags & LOCAL_I915_USERPTR_UNSYNCHRONIZED) == 0 && + !read_only, + "Skipping, synchronized mappings with no kernel CONFIG_MMU_NOTIFIER?"); + if (ret == 0) + *handle = userptr.handle; + + return ret; +} + +/** + * gem_userptr: + * @fd: open i915 drm file descriptor + * @ptr: userptr pointer to be passed + * @size: desired size of the buffer + * @read_only: specify whether userptr is opened read only + * @flags: other userptr flags + * @handle: returned handle for the object + * + * Returns userptr handle for the GEM object. + */ +void gem_userptr(int fd, void *ptr, int size, int read_only, uint32_t flags, uint32_t *handle) +{ + igt_assert_eq(__gem_userptr(fd, ptr, size, read_only, flags, handle), 0); +} + /** * gem_sw_finish: * @fd: open i915 drm file descriptor diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h index 4d913c59..b9a4db6b 100644 --- a/lib/ioctl_wrappers.h +++ b/lib/ioctl_wrappers.h @@ -114,6 +114,19 @@ void gem_context_get_param(int fd, struct local_i915_gem_context_param *p); void gem_context_set_param(int fd, struct local_i915_gem_context_param *p); int __gem_context_set_param(int fd, struct local_i915_gem_context_param *p); +#define LOCAL_I915_GEM_USERPTR 0x33 +#define LOCAL_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_USERPTR, struct local_i915_gem_userptr) +struct local_i915_gem_userptr { + uint64_t user_ptr; + uint64_t user_size; + uint32_t flags; +#define LOCAL_I915_USERPTR_READ_ONLY (1<<0) +#define LOCAL_I915_USERPTR_UNSYNCHRONIZED (1<<31) + uint32_t handle; +}; +void gem_userptr(int fd, void *ptr, int size, int read_only, uint32_t flags, uint32_t *handle); +int __gem_userptr(int fd, void *ptr, int size, int read_only, uint32_t flags, uint32_t *handle); + void gem_sw_finish(int fd, uint32_t handle); bool gem_bo_busy(int fd, uint32_t handle); diff --git a/tests/gem_concurrent_all.c b/tests/gem_concurrent_all.c index 9b7ef870..74da42ca 100644 --- a/tests/gem_concurrent_all.c +++ b/tests/gem_concurrent_all.c @@ -53,15 +53,6 @@ IGT_TEST_DESCRIPTION("Test of pread/pwrite/mmap behavior when writing to active" " buffers."); -#define LOCAL_I915_GEM_USERPTR 0x33 -#define LOCAL_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_USERPTR, struct local_i915_gem_userptr) -struct local_i915_gem_userptr { - uint64_t user_ptr; - uint64_t user_size; - uint32_t flags; - uint32_t handle; -}; - int fd, devid, gen; struct intel_batchbuffer *batch; int all; diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c index a6946d0d..e306d5c5 100644 --- a/tests/gem_userptr_blits.c +++ b/tests/gem_userptr_blits.c @@ -61,17 +61,6 @@ #define PAGE_SIZE 4096 #endif -#define LOCAL_I915_GEM_USERPTR 0x33 -#define LOCAL_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_USERPTR, struct local_i915_gem_userptr) -struct local_i915_gem_userptr { - uint64_t user_ptr; - uint64_t user_size; - uint32_t flags; -#define LOCAL_I915_USERPTR_READ_ONLY (1<<0) -#define LOCAL_I915_USERPTR_UNSYNCHRONIZED (1<<31) - uint32_t handle; -}; - static uint32_t userptr_flags = LOCAL_I915_USERPTR_UNSYNCHRONIZED; #define WIDTH 512 @@ -89,32 +78,6 @@ static void gem_userptr_test_synchronized(void) userptr_flags = 0; } -static int gem_userptr(int fd, void *ptr, int size, int read_only, uint32_t *handle) -{ - struct local_i915_gem_userptr userptr; - int ret; - - memset(&userptr, 0, sizeof(userptr)); - userptr.user_ptr = (uintptr_t)ptr; - userptr.user_size = size; - userptr.flags = userptr_flags; - if (read_only) - userptr.flags |= LOCAL_I915_USERPTR_READ_ONLY; - - ret = drmIoctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &userptr); - if (ret) - ret = errno; - igt_skip_on_f(ret == ENODEV && - (userptr_flags & LOCAL_I915_USERPTR_UNSYNCHRONIZED) == 0 && - !read_only, - "Skipping, synchronized mappings with no kernel CONFIG_MMU_NOTIFIER?"); - if (ret == 0) - *handle = userptr.handle; - - return ret; -} - - static void gem_userptr_sync(int fd, uint32_t handle) { gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); @@ -270,10 +233,9 @@ static uint32_t create_userptr(int fd, uint32_t val, uint32_t *ptr) { uint32_t handle; - int i, ret; + int i; - ret = gem_userptr(fd, ptr, sizeof(linear), 0, &handle); - igt_assert_eq(ret, 0); + gem_userptr(fd, ptr, sizeof(linear), 0, userptr_flags, &handle); igt_assert(handle != 0); /* Fill the BO with dwords starting at val */ @@ -344,7 +306,6 @@ static uint32_t create_userptr_bo(int fd, uint64_t size) { void *ptr; uint32_t handle; - int ret; ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, @@ -352,8 +313,7 @@ static uint32_t create_userptr_bo(int fd, uint64_t size) -1, 0); igt_assert(ptr != MAP_FAILED); - ret = gem_userptr(fd, (uint32_t *)ptr, size, 0, &handle); - igt_assert_eq(ret, 0); + gem_userptr(fd, (uint32_t *)ptr, size, 0, userptr_flags, &handle); add_handle_ptr(handle, ptr, size); return handle; @@ -431,7 +391,7 @@ static int has_userptr(int fd) igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); oldflags = userptr_flags; gem_userptr_test_unsynchronized(); - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle); + ret = __gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle); userptr_flags = oldflags; if (ret != 0) { free(ptr); @@ -490,7 +450,7 @@ static int test_access_control(int fd) igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle); + ret = __gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle); if (ret == 0) gem_close(fd, handle); free(ptr); @@ -505,11 +465,9 @@ static int test_access_control(int fd) static int test_invalid_null_pointer(int fd) { uint32_t handle; - int ret; /* NULL pointer. */ - ret = gem_userptr(fd, NULL, PAGE_SIZE, 0, &handle); - igt_assert_eq(ret, 0); + gem_userptr(fd, NULL, PAGE_SIZE, 0, userptr_flags, &handle); copy(fd, handle, handle, ~0); /* QQQ Precise errno? */ gem_close(fd, handle); @@ -521,7 +479,6 @@ static int test_invalid_gtt_mapping(int fd) { uint32_t handle, handle2; void *ptr; - int ret; /* GTT mapping */ handle = create_bo(fd, 0); @@ -531,8 +488,7 @@ static int test_invalid_gtt_mapping(int fd) igt_assert(((unsigned long)ptr & (PAGE_SIZE - 1)) == 0); igt_assert((sizeof(linear) & (PAGE_SIZE - 1)) == 0); - ret = gem_userptr(fd, ptr, sizeof(linear), 0, &handle2); - igt_assert_eq(ret, 0); + gem_userptr(fd, ptr, sizeof(linear), 0, userptr_flags, &handle2); copy(fd, handle2, handle2, ~0); /* QQQ Precise errno? */ gem_close(fd, handle2); @@ -575,8 +531,7 @@ static void test_forked_access(int fd) #ifdef MADV_DONTFORK ret |= madvise(ptr1, sizeof(linear), MADV_DONTFORK); #endif - ret |= gem_userptr(fd, ptr1, sizeof(linear), 0, &handle1); - igt_assert_eq(ret, 0); + gem_userptr(fd, ptr1, sizeof(linear), 0, userptr_flags, &handle1); igt_assert(ptr1); igt_assert(handle1); @@ -584,8 +539,7 @@ static void test_forked_access(int fd) #ifdef MADV_DONTFORK ret |= madvise(ptr2, sizeof(linear), MADV_DONTFORK); #endif - ret |= gem_userptr(fd, ptr2, sizeof(linear), 0, &handle2); - igt_assert_eq(ret, 0); + gem_userptr(fd, ptr2, sizeof(linear), 0, userptr_flags, &handle2); igt_assert(ptr2); igt_assert(handle2); @@ -632,8 +586,7 @@ static int test_forbidden_ops(int fd) igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle); - igt_assert_eq(ret, 0); + gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle); /* pread/pwrite are not always forbidden, but when they * are they should fail with EINVAL. @@ -671,7 +624,7 @@ static void test_relocations(int fd) memset(&obj, 0, sizeof(obj)); igt_assert(posix_memalign(&ptr, PAGE_SIZE, size) == 0); - igt_assert_eq(gem_userptr(fd, ptr, size, 0, &obj.handle), 0); + gem_userptr(fd, ptr, size, 0, userptr_flags, &obj.handle); if (!gem_has_llc(fd)) gem_set_caching(fd, obj.handle, 0); *(uint32_t *)ptr = MI_BATCH_BUFFER_END; @@ -859,19 +812,19 @@ static int test_usage_restrictions(int fd) igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE * 2) == 0); /* Address not aligned. */ - ret = gem_userptr(fd, (char *)ptr + 1, PAGE_SIZE, 0, &handle); + ret = __gem_userptr(fd, (char *)ptr + 1, PAGE_SIZE, 0, userptr_flags, &handle); igt_assert_neq(ret, 0); /* Size not rounded to page size. */ - ret = gem_userptr(fd, ptr, PAGE_SIZE - 1, 0, &handle); + ret = __gem_userptr(fd, ptr, PAGE_SIZE - 1, 0, userptr_flags, &handle); igt_assert_neq(ret, 0); /* Both wrong. */ - ret = gem_userptr(fd, (char *)ptr + 1, PAGE_SIZE - 1, 0, &handle); + ret = __gem_userptr(fd, (char *)ptr + 1, PAGE_SIZE - 1, 0, userptr_flags, &handle); igt_assert_neq(ret, 0); /* Read-only not supported. */ - ret = gem_userptr(fd, (char *)ptr, PAGE_SIZE, 1, &handle); + ret = __gem_userptr(fd, (char *)ptr, PAGE_SIZE, 1, userptr_flags, &handle); igt_assert_neq(ret, 0); free(ptr); @@ -893,7 +846,7 @@ static int test_create_destroy(int fd, int time) for (n = 0; n < 1000; n++) { igt_assert(posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE) == 0); - do_or_die(gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle)); + do_or_die(__gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle)); gem_close(fd, handle); free(ptr); @@ -1086,41 +1039,40 @@ static void test_overlap(int fd, int expected) igt_assert(posix_memalign((void *)&ptr, PAGE_SIZE, PAGE_SIZE * 3) == 0); - ret = gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE, 0, &handle); - igt_assert_eq(ret, 0); + gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE, 0, userptr_flags, &handle); /* before, no overlap */ - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle2); + ret = __gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle2); if (ret == 0) gem_close(fd, handle2); igt_assert_eq(ret, 0); /* after, no overlap */ - ret = gem_userptr(fd, ptr + PAGE_SIZE * 2, PAGE_SIZE, 0, &handle2); + ret = __gem_userptr(fd, ptr + PAGE_SIZE * 2, PAGE_SIZE, 0, userptr_flags, &handle2); if (ret == 0) gem_close(fd, handle2); igt_assert_eq(ret, 0); /* exactly overlapping */ - ret = gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE, 0, &handle2); + ret = __gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE, 0, userptr_flags, &handle2); if (ret == 0) gem_close(fd, handle2); igt_assert(ret == 0 || ret == expected); /* start overlaps */ - ret = gem_userptr(fd, ptr, PAGE_SIZE * 2, 0, &handle2); + ret = __gem_userptr(fd, ptr, PAGE_SIZE * 2, 0, userptr_flags, &handle2); if (ret == 0) gem_close(fd, handle2); igt_assert(ret == 0 || ret == expected); /* end overlaps */ - ret = gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE * 2, 0, &handle2); + ret = __gem_userptr(fd, ptr + PAGE_SIZE, PAGE_SIZE * 2, 0, userptr_flags, &handle2); if (ret == 0) gem_close(fd, handle2); igt_assert(ret == 0 || ret == expected); /* subsumes */ - ret = gem_userptr(fd, ptr, PAGE_SIZE * 3, 0, &handle2); + ret = __gem_userptr(fd, ptr, PAGE_SIZE * 3, 0, userptr_flags, &handle2); if (ret == 0) gem_close(fd, handle2); igt_assert(ret == 0 || ret == expected); @@ -1145,8 +1097,7 @@ static void test_unmap(int fd, int expected) bo_ptr = (char *)ALIGN((unsigned long)ptr, PAGE_SIZE); for (i = 0; i < num_obj; i++, bo_ptr += sizeof(linear)) { - ret = gem_userptr(fd, bo_ptr, sizeof(linear), 0, &bo[i]); - igt_assert_eq(ret, 0); + gem_userptr(fd, bo_ptr, sizeof(linear), 0, userptr_flags, &bo[i]); } bo[num_obj] = create_bo(fd, 0); @@ -1180,8 +1131,7 @@ static void test_unmap_after_close(int fd) bo_ptr = (char *)ALIGN((unsigned long)ptr, PAGE_SIZE); for (i = 0; i < num_obj; i++, bo_ptr += sizeof(linear)) { - ret = gem_userptr(fd, bo_ptr, sizeof(linear), 0, &bo[i]); - igt_assert_eq(ret, 0); + gem_userptr(fd, bo_ptr, sizeof(linear), 0, userptr_flags, &bo[i]); } bo[num_obj] = create_bo(fd, 0); @@ -1251,8 +1201,7 @@ static void test_stress_mm(int fd) igt_assert_eq(ret, 0); while (loops--) { - ret = gem_userptr(fd, ptr, PAGE_SIZE, 0, &handle); - igt_assert_eq(ret, 0); + gem_userptr(fd, ptr, PAGE_SIZE, 0, userptr_flags, &handle); gem_close(fd, handle); } @@ -1286,8 +1235,7 @@ static void *mm_userptr_close_thread(void *data) while (!t->stop) { pthread_mutex_unlock(&t->mutex); for (int i = 0; i < num_handles; i++) - igt_assert_eq(gem_userptr(t->fd, t->ptr, PAGE_SIZE, 0, &handle[i]), - 0); + gem_userptr(t->fd, t->ptr, PAGE_SIZE, 0, userptr_flags, &handle[i]); for (int i = 0; i < num_handles; i++) gem_close(t->fd, handle[i]); pthread_mutex_lock(&t->mutex); -- cgit v1.2.3