summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ioctl_wrappers.c33
-rw-r--r--lib/ioctl_wrappers.h4
-rw-r--r--tests/gem_userptr_blits.c77
3 files changed, 100 insertions, 14 deletions
diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index 32cb0f36..4d30443f 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -403,29 +403,38 @@ void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t leng
igt_assert_eq(__gem_read(fd, handle, offset, buf, length), 0);
}
+int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
+{
+ struct drm_i915_gem_set_domain set_domain;
+ int err;
+
+ memset(&set_domain, 0, sizeof(set_domain));
+ set_domain.handle = handle;
+ set_domain.read_domains = read;
+ set_domain.write_domain = write;
+
+ err = 0;
+ if (igt_ioctl(fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain))
+ err = -errno;
+
+ return err;
+}
+
/**
* gem_set_domain:
* @fd: open i915 drm file descriptor
* @handle: gem buffer object handle
- * @read_domains: gem domain bits for read access
- * @write_domain: gem domain bit for write access
+ * @read: gem domain bits for read access
+ * @write: gem domain bit for write access
*
* This wraps the SET_DOMAIN ioctl, which is used to control the coherency of
* the gem buffer object between the cpu and gtt mappings. It is also use to
* synchronize with outstanding rendering in general, but for that use-case
* please have a look at gem_sync().
*/
-void gem_set_domain(int fd, uint32_t handle,
- uint32_t read_domains, uint32_t write_domain)
+void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write)
{
- struct drm_i915_gem_set_domain set_domain;
-
- memset(&set_domain, 0, sizeof(set_domain));
- set_domain.handle = handle;
- set_domain.read_domains = read_domains;
- set_domain.write_domain = write_domain;
-
- do_ioctl(fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
+ igt_assert_eq(__gem_set_domain(fd, handle, read, write), 0);
}
/**
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index af061ef3..56c5d14c 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -65,8 +65,8 @@ void gem_close(int fd, uint32_t handle);
int __gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length);
void gem_write(int fd, uint32_t handle, uint64_t offset, const void *buf, uint64_t length);
void gem_read(int fd, uint32_t handle, uint64_t offset, void *buf, uint64_t length);
-void gem_set_domain(int fd, uint32_t handle,
- uint32_t read_domains, uint32_t write_domain);
+int __gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
+void gem_set_domain(int fd, uint32_t handle, uint32_t read, uint32_t write);
int gem_wait(int fd, uint32_t handle, int64_t *timeout_ns);
void gem_sync(int fd, uint32_t handle);
bool gem_create__has_stolen_support(int fd);
diff --git a/tests/gem_userptr_blits.c b/tests/gem_userptr_blits.c
index 0df53105..49a7f2f4 100644
--- a/tests/gem_userptr_blits.c
+++ b/tests/gem_userptr_blits.c
@@ -614,6 +614,74 @@ static void test_forked_access(int fd)
free(ptr2);
}
+#define MAP_FIXED_INVALIDATE_OVERLAP (1<<0)
+#define MAP_FIXED_INVALIDATE_BUSY (1<<1)
+#define MAP_FIXED_INVALIDATE_GET_PAGES (1<<2)
+#define ALL_MAP_FIXED_INVALIDATE (MAP_FIXED_INVALIDATE_OVERLAP | \
+ MAP_FIXED_INVALIDATE_BUSY | \
+ MAP_FIXED_INVALIDATE_GET_PAGES)
+
+static int test_map_fixed_invalidate(int fd, uint32_t flags)
+{
+ const size_t ptr_size = sizeof(linear) + 2*PAGE_SIZE;
+ const int num_handles = (flags & MAP_FIXED_INVALIDATE_OVERLAP) ? 2 : 1;
+ uint32_t handle[num_handles];
+ uint32_t *ptr;
+
+ ptr = mmap(NULL, ptr_size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS,
+ -1, 0);
+ igt_assert(ptr != MAP_FAILED);
+
+ for (int i = 0; i < num_handles; i++)
+ handle[i] = create_userptr(fd, 0, ptr + PAGE_SIZE/sizeof(*ptr));
+
+ for (char *fixed = (char *)ptr, *end = fixed + ptr_size;
+ fixed + 2*PAGE_SIZE <= end;
+ fixed += PAGE_SIZE) {
+ struct drm_i915_gem_mmap_gtt mmap_gtt;
+ char *map;
+
+ ptr = mmap(ptr, ptr_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED,
+ -1, 0);
+
+ memset(&mmap_gtt, 0, sizeof(mmap_gtt));
+ mmap_gtt.handle = gem_create(fd, 2*PAGE_SIZE);
+ do_ioctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_gtt);
+
+ if (flags & MAP_FIXED_INVALIDATE_BUSY)
+ copy(fd, handle[0], handle[num_handles-1], 0);
+
+ map = mmap(fixed, 2*PAGE_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_FIXED,
+ fd, mmap_gtt.offset);
+ igt_assert(map == fixed);
+
+ gem_set_tiling(fd, mmap_gtt.handle, I915_TILING_NONE, 0);
+ *(uint32_t*)map = 0xdead;
+
+ if (flags & MAP_FIXED_INVALIDATE_GET_PAGES)
+ igt_assert_eq(__gem_set_domain(fd, handle[0],
+ I915_GEM_DOMAIN_GTT,
+ I915_GEM_DOMAIN_GTT),
+ -EFAULT);
+
+ gem_set_tiling(fd, mmap_gtt.handle, I915_TILING_Y, 512 * 4);
+ *(uint32_t*)map = 0xbeef;
+
+ gem_close(fd, mmap_gtt.handle);
+ }
+
+ for (int i = 0; i < num_handles; i++)
+ gem_close(fd, handle[i]);
+ munmap(ptr, ptr_size);
+
+ return 0;
+}
+
static int test_forbidden_ops(int fd)
{
struct drm_i915_gem_pread gem_pread;
@@ -1504,6 +1572,15 @@ int main(int argc, char **argv)
igt_subtest("stress-mm-invalidate-close-overlap")
test_invalidate_close_race(fd, true);
+ for (unsigned flags = 0; flags < ALL_MAP_FIXED_INVALIDATE + 1; flags++) {
+ igt_subtest_f("map-fixed-invalidate%s%s%s",
+ flags & MAP_FIXED_INVALIDATE_OVERLAP ? "-overlap" : "",
+ flags & MAP_FIXED_INVALIDATE_BUSY ? "-busy" : "",
+ flags & MAP_FIXED_INVALIDATE_GET_PAGES ? "-gup" : "") {
+ test_map_fixed_invalidate(fd, flags);
+ }
+ }
+
igt_subtest("coherency-sync")
test_coherency(fd, count);