All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH igt] vgem: Add basic dma-buf fence interop
Date: Wed, 22 Jun 2016 09:02:26 +0100	[thread overview]
Message-ID: <1466582546-28083-1-git-send-email-chris@chris-wilson.co.uk> (raw)

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 lib/igt_vgem.c     | 70 ++++++++++++++++++++++++++++++++++++++
 lib/igt_vgem.h     |  4 +++
 tests/prime_vgem.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 tests/vgem_basic.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 259 insertions(+), 5 deletions(-)

diff --git a/lib/igt_vgem.c b/lib/igt_vgem.c
index 4fe166a..95731d9 100644
--- a/lib/igt_vgem.c
+++ b/lib/igt_vgem.c
@@ -80,3 +80,73 @@ void *vgem_mmap(int fd, struct vgem_bo *bo, unsigned prot)
 	return ptr;
 }
 
+#define LOCAL_VGEM_FENCE_ATTACH   0x1
+#define LOCAL_VGEM_FENCE_SIGNAL   0x2
+
+#define LOCAL_IOCTL_VGEM_FENCE_ATTACH     DRM_IOWR( DRM_COMMAND_BASE + LOCAL_VGEM_FENCE_ATTACH, struct local_vgem_fence_attach)
+#define LOCAL_IOCTL_VGEM_FENCE_SIGNAL     DRM_IOW( DRM_COMMAND_BASE + LOCAL_VGEM_FENCE_SIGNAL, struct local_vgem_fence_signal)
+
+struct local_vgem_fence_attach {
+	uint32_t handle;
+	uint32_t flags;
+#define VGEM_FENCE_WRITE 0x1
+	uint32_t out_fence;
+	uint32_t pad;
+};
+
+struct local_vgem_fence_signal {
+	uint32_t fence;
+	uint32_t flags;
+};
+
+bool vgem_has_fences(int fd)
+{
+	struct local_vgem_fence_signal arg;
+	int err;
+
+	err = 0;
+	memset(&arg, 0, sizeof(arg));
+	if (drmIoctl(fd, LOCAL_IOCTL_VGEM_FENCE_SIGNAL, &arg))
+		err = -errno;
+	errno = 0;
+	return err == -ENOENT;
+}
+
+static int __vgem_fence_attach(int fd, struct local_vgem_fence_attach *arg)
+{
+	int err = 0;
+	if (igt_ioctl(fd, LOCAL_IOCTL_VGEM_FENCE_ATTACH, arg))
+		err = -errno;
+	errno = 0;
+	return err;
+}
+
+uint32_t vgem_fence_attach(int fd, struct vgem_bo *bo, bool write)
+{
+	struct local_vgem_fence_attach arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.handle = bo->handle;
+	if (write)
+		arg.flags |= VGEM_FENCE_WRITE;
+	igt_assert_eq(__vgem_fence_attach(fd, &arg), 0);
+	return arg.out_fence;
+}
+
+static int __vgem_fence_signal(int fd, struct local_vgem_fence_signal *arg)
+{
+	int err = 0;
+	if (igt_ioctl(fd, LOCAL_IOCTL_VGEM_FENCE_SIGNAL, arg))
+		err = -errno;
+	errno = 0;
+	return err;
+}
+
+void vgem_fence_signal(int fd, uint32_t fence)
+{
+	struct local_vgem_fence_signal arg;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.fence = fence;
+	igt_assert_eq(__vgem_fence_signal(fd, &arg), 0);
+}
diff --git a/lib/igt_vgem.h b/lib/igt_vgem.h
index 9e4a55e..91c77ba 100644
--- a/lib/igt_vgem.h
+++ b/lib/igt_vgem.h
@@ -39,4 +39,8 @@ void vgem_create(int fd, struct vgem_bo *bo);
 void *__vgem_mmap(int fd, struct vgem_bo *bo, unsigned prot);
 void *vgem_mmap(int fd, struct vgem_bo *bo, unsigned prot);
 
+bool vgem_has_fences(int fd);
+uint32_t vgem_fence_attach(int fd, struct vgem_bo *bo, bool write);
+void vgem_fence_signal(int fd, uint32_t fence);
+
 #endif /* IGT_VGEM_H */
diff --git a/tests/prime_vgem.c b/tests/prime_vgem.c
index 6bdd567..be4a43c 100644
--- a/tests/prime_vgem.c
+++ b/tests/prime_vgem.c
@@ -309,21 +309,88 @@ static void test_sync(int i915, int vgem, unsigned ring, uint32_t flags)
 	vgem_create(vgem, &scratch);
 	dmabuf = prime_handle_to_fd(vgem, scratch.handle);
 
+	ptr = mmap(NULL, scratch.size, PROT_READ, MAP_SHARED, dmabuf, 0);
+	igt_assert(ptr != MAP_FAILED);
+	gem_close(vgem, scratch.handle);
+
 	work(i915, dmabuf, ring, flags);
 
 	prime_sync_start(dmabuf, false);
-
-	ptr = vgem_mmap(vgem, &scratch, PROT_READ);
 	for (i = 0; i < 1024; i++)
 		igt_assert_eq_u32(ptr[i], i);
-	munmap(ptr, 4096);
 
 	prime_sync_end(dmabuf, false);
+	close(dmabuf);
+
+	munmap(ptr, scratch.size);
+}
+
+static void test_fence_wait(int i915, int vgem, unsigned ring, unsigned flags)
+{
+	struct vgem_bo scratch;
+	uint32_t fence;
+	uint32_t *ptr;
+	int dmabuf;
+
+	scratch.width = 1024;
+	scratch.height = 1;
+	scratch.bpp = 32;
+	vgem_create(vgem, &scratch);
 
+	dmabuf = prime_handle_to_fd(vgem, scratch.handle);
+	fence = vgem_fence_attach(vgem, &scratch, true);
 	gem_close(vgem, scratch.handle);
+
+	igt_fork(child, 1)
+		work(i915, dmabuf, ring, flags);
+
+	sleep(1);
+	vgem_fence_signal(vgem, fence);
+	igt_waitchildren();
+
+	ptr = mmap(NULL, scratch.size, PROT_READ, MAP_SHARED, dmabuf, 0);
+	igt_assert(ptr != MAP_FAILED);
+
+	prime_sync_start(dmabuf, false);
+	for (int i = 0; i < 1024; i++)
+		igt_assert_eq_u32(ptr[i], i);
+	prime_sync_end(dmabuf, false);
+	munmap(ptr, scratch.size);
+
 	close(dmabuf);
 }
 
+static void test_fence_hang(int i915, int vgem, bool write)
+{
+	struct vgem_bo scratch;
+	uint32_t *ptr;
+	int dmabuf;
+	int i;
+
+	scratch.width = 1024;
+	scratch.height = 1;
+	scratch.bpp = 32;
+	vgem_create(vgem, &scratch);
+	dmabuf = prime_handle_to_fd(vgem, scratch.handle);
+	vgem_fence_attach(vgem, &scratch, write);
+
+	ptr = mmap(NULL, scratch.size, PROT_READ, MAP_SHARED, dmabuf, 0);
+	igt_assert(ptr != MAP_FAILED);
+	gem_close(vgem, scratch.handle);
+
+	work(i915, dmabuf, I915_EXEC_DEFAULT, 0);
+
+	/* The work should have been cancelled */
+
+	prime_sync_start(dmabuf, false);
+	for (i = 0; i < 1024; i++)
+		igt_assert_eq_u32(ptr[i], 0);
+	prime_sync_end(dmabuf, false);
+	close(dmabuf);
+
+	munmap(ptr, scratch.size);
+}
+
 static bool has_prime_export(int fd)
 {
 	uint64_t value;
@@ -411,6 +478,31 @@ igt_main
 		}
 	}
 
+	/* Fence testing */
+	igt_subtest_group {
+		igt_fixture {
+			igt_require(vgem_has_fences(vgem));
+		}
+
+		for (e = intel_execution_engines; e->name; e++) {
+			igt_subtest_f("%sfence-wait-%s",
+					e->exec_id == 0 ? "basic-" : "",
+					e->name) {
+				gem_require_ring(i915, e->exec_id | e->flags);
+				igt_skip_on_f(gen == 6 &&
+						e->exec_id == I915_EXEC_BSD,
+						"MI_STORE_DATA broken on gen6 bsd\n");
+				gem_quiescent_gpu(i915);
+				test_fence_wait(i915, vgem, e->exec_id, e->flags);
+			}
+		}
+
+		igt_subtest("fence-read-hang")
+			test_fence_hang(i915, vgem, false);
+		igt_subtest("fence-write-hang")
+			test_fence_hang(i915, vgem, true);
+	}
+
 	igt_fixture {
 		close(i915);
 		close(vgem);
diff --git a/tests/vgem_basic.c b/tests/vgem_basic.c
index b4337ee..9feabf7 100644
--- a/tests/vgem_basic.c
+++ b/tests/vgem_basic.c
@@ -27,6 +27,7 @@
 #include "igt_sysfs.h"
 
 #include <sys/mman.h>
+#include <sys/poll.h>
 #include <sys/stat.h>
 #include <dirent.h>
 
@@ -144,6 +145,82 @@ static void test_dmabuf_mmap(int fd)
 	munmap(ptr, bo.size);
 }
 
+static bool prime_busy(int fd, bool excl)
+{
+	struct pollfd pfd = { .fd = fd, .events = excl ? POLLOUT : POLLIN };
+	return poll(&pfd, 1, 0) == 0;
+}
+
+static void test_dmabuf_fence(int fd)
+{
+	struct vgem_bo bo;
+	int dmabuf;
+	uint32_t fence;
+
+	bo.width = 1024;
+	bo.height = 1;
+	bo.bpp = 32;
+	vgem_create(fd, &bo);
+
+	/* export, then fence */
+
+	dmabuf = prime_handle_to_fd(fd, bo.handle);
+
+	fence = vgem_fence_attach(fd, &bo, false);
+	igt_assert(!prime_busy(dmabuf, false));
+	igt_assert(prime_busy(dmabuf, true));
+
+	vgem_fence_signal(fd, fence);
+	igt_assert(!prime_busy(dmabuf, false));
+	igt_assert(!prime_busy(dmabuf, true));
+
+	fence = vgem_fence_attach(fd, &bo, true);
+	igt_assert(prime_busy(dmabuf, false));
+	igt_assert(prime_busy(dmabuf, true));
+
+	vgem_fence_signal(fd, fence);
+	igt_assert(!prime_busy(dmabuf, false));
+	igt_assert(!prime_busy(dmabuf, true));
+
+	gem_close(fd, bo.handle);
+}
+
+static void test_dmabuf_fence_before(int fd)
+{
+	struct vgem_bo bo;
+	int dmabuf;
+	uint32_t fence;
+
+	bo.width = 1024;
+	bo.height = 1;
+	bo.bpp = 32;
+	vgem_create(fd, &bo);
+
+	fence = vgem_fence_attach(fd, &bo, false);
+	dmabuf = prime_handle_to_fd(fd, bo.handle);
+
+	igt_assert(!prime_busy(dmabuf, false));
+	igt_assert(prime_busy(dmabuf, true));
+
+	vgem_fence_signal(fd, fence);
+	igt_assert(!prime_busy(dmabuf, false));
+	igt_assert(!prime_busy(dmabuf, true));
+
+	gem_close(fd, bo.handle);
+	vgem_create(fd, &bo);
+
+	fence = vgem_fence_attach(fd, &bo, true);
+	dmabuf = prime_handle_to_fd(fd, bo.handle);
+	igt_assert(prime_busy(dmabuf, false));
+	igt_assert(prime_busy(dmabuf, true));
+
+	vgem_fence_signal(fd, fence);
+	igt_assert(!prime_busy(dmabuf, false));
+	igt_assert(!prime_busy(dmabuf, true));
+
+	gem_close(fd, bo.handle);
+}
+
 static void test_sysfs_read(int fd)
 {
 	int dir = igt_sysfs_open(fd, NULL);
@@ -229,11 +306,22 @@ igt_main
 			igt_require(has_prime_export(fd));
 		}
 
-		igt_subtest_f("dmabuf-export")
+		igt_subtest("dmabuf-export")
 			test_dmabuf_export(fd);
 
-		igt_subtest_f("dmabuf-mmap")
+		igt_subtest("dmabuf-mmap")
 			test_dmabuf_mmap(fd);
+
+		igt_subtest_group {
+			igt_fixture {
+				igt_require(vgem_has_fences(fd));
+			}
+
+			igt_subtest("dmabuf-fence")
+				test_dmabuf_fence(fd);
+			igt_subtest("dmabuf-fence-before")
+				test_dmabuf_fence_before(fd);
+		}
 	}
 
 	igt_subtest("sysfs")
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

                 reply	other threads:[~2016-06-22  8:02 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1466582546-28083-1-git-send-email-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.