All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing
@ 2019-11-20 21:21 Lionel Landwerlin
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 01/10] lib/syncobj: drop local declarations Lionel Landwerlin
                   ` (12 more replies)
  0 siblings, 13 replies; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-20 21:21 UTC (permalink / raw)
  To: igt-dev

Hi all,

This is a resend of the same series from a few months back to add
testing for timeline syncobjs.

There are two parts :

  - some generic testing mostly from David at AMD that does not rely
    on a particular driver

  - some i915 specific tests using a new uAPI to plumb the timeline
    points along the syncobj handles

Cheers,

Chunming Zhou (1):
  igt: add timeline test cases

Lionel Landwerlin (9):
  lib/syncobj: drop local declarations
  drm-uapi: Update drm headers to
    17cc51390c141662748dbbc2fe98f3ed10f2e13e
  tests/syncobj_timeline: add more timeline tests
  tests/i915/exec_fence: switch to internal headers
  tests/i915/exec_fence: reuse syncobj helpers
  include: bump drm headers for i915 timeline semaphores
  tests/i915/exec_fence: add timeline fence tests
  lib/i915: add mmio base for engines
  tests/i915/gem_exec_fence: add engine chaining tests

 include/drm-uapi/amdgpu_drm.h   |   71 +-
 include/drm-uapi/drm.h          |   56 +
 include/drm-uapi/drm_fourcc.h   |   28 +-
 include/drm-uapi/drm_mode.h     |  122 ++-
 include/drm-uapi/etnaviv_drm.h  |   10 +-
 include/drm-uapi/exynos_drm.h   |    2 +-
 include/drm-uapi/i915_drm.h     |   64 +-
 include/drm-uapi/msm_drm.h      |   14 +
 include/drm-uapi/nouveau_drm.h  |   51 +
 include/drm-uapi/omap_drm.h     |   18 +-
 include/drm-uapi/panfrost_drm.h |   88 ++
 include/drm-uapi/v3d_drm.h      |   36 +-
 lib/i915/gem_engine_topology.c  |   74 ++
 lib/i915/gem_engine_topology.h  |    5 +
 lib/igt_syncobj.c               |  252 ++++-
 lib/igt_syncobj.h               |   48 +-
 lib/intel_reg.h                 |    2 +
 tests/i915/gem_exec_fence.c     | 1821 +++++++++++++++++++++++++------
 tests/meson.build               |    1 +
 tests/syncobj_basic.c           |    2 +-
 tests/syncobj_timeline.c        | 1537 ++++++++++++++++++++++++++
 tests/syncobj_wait.c            |   58 +-
 22 files changed, 3925 insertions(+), 435 deletions(-)
 create mode 100644 tests/syncobj_timeline.c

--
2.24.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [igt-dev] [PATCH i-g-t 01/10] lib/syncobj: drop local declarations
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
@ 2019-11-20 21:21 ` Lionel Landwerlin
  2019-11-20 21:49   ` Chris Wilson
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 02/10] drm-uapi: Update drm headers to 17cc51390c141662748dbbc2fe98f3ed10f2e13e Lionel Landwerlin
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-20 21:21 UTC (permalink / raw)
  To: igt-dev

We have copies of the DRM uAPI headers in the repo, so drop the local
declaration of syncobj defines/types.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 lib/igt_syncobj.c     | 16 ++++++------
 lib/igt_syncobj.h     | 26 +------------------
 tests/syncobj_basic.c |  2 +-
 tests/syncobj_wait.c  | 58 +++++++++++++++++++++----------------------
 4 files changed, 39 insertions(+), 63 deletions(-)

diff --git a/lib/igt_syncobj.c b/lib/igt_syncobj.c
index 0fddb97a..e5569ffc 100644
--- a/lib/igt_syncobj.c
+++ b/lib/igt_syncobj.c
@@ -170,10 +170,10 @@ syncobj_import_sync_file(int fd, uint32_t handle, int sync_file)
 }
 
 int
-__syncobj_wait(int fd, struct local_syncobj_wait *args)
+__syncobj_wait(int fd, struct drm_syncobj_wait *args)
 {
 	int err = 0;
-	if (drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_WAIT, args))
+	if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, args))
 		err = -errno;
 	return err;
 }
@@ -182,7 +182,7 @@ int
 syncobj_wait_err(int fd, uint32_t *handles, uint32_t count,
 		 uint64_t abs_timeout_nsec, uint32_t flags)
 {
-	struct local_syncobj_wait wait;
+	struct drm_syncobj_wait wait;
 
 	wait.handles = to_user_pointer(handles);
 	wait.timeout_nsec = abs_timeout_nsec;
@@ -212,7 +212,7 @@ syncobj_wait(int fd, uint32_t *handles, uint32_t count,
 	     uint64_t abs_timeout_nsec, uint32_t flags,
 	     uint32_t *first_signaled)
 {
-	struct local_syncobj_wait wait;
+	struct drm_syncobj_wait wait;
 	int ret;
 
 	wait.handles = to_user_pointer(handles);
@@ -236,12 +236,12 @@ syncobj_wait(int fd, uint32_t *handles, uint32_t count,
 static int
 __syncobj_reset(int fd, uint32_t *handles, uint32_t count)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	int err = 0;
 
 	array.handles = to_user_pointer(handles);
 	array.count_handles = count;
-	if (drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array))
+	if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_RESET, &array))
 		err = -errno;
 	return err;
 }
@@ -263,12 +263,12 @@ syncobj_reset(int fd, uint32_t *handles, uint32_t count)
 static int
 __syncobj_signal(int fd, uint32_t *handles, uint32_t count)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	int err = 0;
 
 	array.handles = to_user_pointer(handles);
 	array.count_handles = count;
-	if (drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array))
+	if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &array))
 		err = -errno;
 	return err;
 }
diff --git a/lib/igt_syncobj.h b/lib/igt_syncobj.h
index 44d1378d..51ad2364 100644
--- a/lib/igt_syncobj.h
+++ b/lib/igt_syncobj.h
@@ -28,30 +28,6 @@
 #include <stdbool.h>
 #include <drm.h>
 
-#define LOCAL_SYNCOBJ_CREATE_SIGNALED (1 << 0)
-
-#define LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
-#define LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
-struct local_syncobj_wait {
-       __u64 handles;
-       /* absolute timeout */
-       __s64 timeout_nsec;
-       __u32 count_handles;
-       __u32 flags;
-       __u32 first_signaled; /* only valid when not waiting all */
-       __u32 pad;
-};
-
-struct local_syncobj_array {
-       __u64 handles;
-       __u32 count_handles;
-       __u32 pad;
-};
-
-#define LOCAL_IOCTL_SYNCOBJ_WAIT	DRM_IOWR(0xC3, struct local_syncobj_wait)
-#define LOCAL_IOCTL_SYNCOBJ_RESET	DRM_IOWR(0xC4, struct local_syncobj_array)
-#define LOCAL_IOCTL_SYNCOBJ_SIGNAL	DRM_IOWR(0xC5, struct local_syncobj_array)
-
 uint32_t syncobj_create(int fd, uint32_t flags);
 void syncobj_destroy(int fd, uint32_t handle);
 int __syncobj_handle_to_fd(int fd, struct drm_syncobj_handle *args);
@@ -59,7 +35,7 @@ int __syncobj_fd_to_handle(int fd, struct drm_syncobj_handle *args);
 int syncobj_handle_to_fd(int fd, uint32_t handle, uint32_t flags);
 uint32_t syncobj_fd_to_handle(int fd, int syncobj_fd, uint32_t flags);
 void syncobj_import_sync_file(int fd, uint32_t handle, int sync_file);
-int __syncobj_wait(int fd, struct local_syncobj_wait *args);
+int __syncobj_wait(int fd, struct drm_syncobj_wait *args);
 int syncobj_wait_err(int fd, uint32_t *handles, uint32_t count,
 		     uint64_t abs_timeout_nsec, uint32_t flags);
 bool syncobj_wait(int fd, uint32_t *handles, uint32_t count,
diff --git a/tests/syncobj_basic.c b/tests/syncobj_basic.c
index 44769d3b..1dce45c9 100644
--- a/tests/syncobj_basic.c
+++ b/tests/syncobj_basic.c
@@ -149,7 +149,7 @@ test_bad_create_flags(int fd)
 static void
 test_create_signaled(int fd)
 {
-	uint32_t syncobj = syncobj_create(fd, LOCAL_SYNCOBJ_CREATE_SIGNALED);
+	uint32_t syncobj = syncobj_create(fd, DRM_SYNCOBJ_CREATE_SIGNALED);
 
 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, 0), 0);
 
diff --git a/tests/syncobj_wait.c b/tests/syncobj_wait.c
index 04d79de7..669d0adf 100644
--- a/tests/syncobj_wait.c
+++ b/tests/syncobj_wait.c
@@ -140,7 +140,7 @@ syncobj_trigger_delayed(int fd, uint32_t syncobj, uint64_t nsec)
 static void
 test_wait_bad_flags(int fd)
 {
-	struct local_syncobj_wait wait = { 0 };
+	struct drm_syncobj_wait wait = { 0 };
 	wait.flags = 0xdeadbeef;
 	igt_assert_eq(__syncobj_wait(fd, &wait), -EINVAL);
 }
@@ -148,14 +148,14 @@ test_wait_bad_flags(int fd)
 static void
 test_wait_zero_handles(int fd)
 {
-	struct local_syncobj_wait wait = { 0 };
+	struct drm_syncobj_wait wait = { 0 };
 	igt_assert_eq(__syncobj_wait(fd, &wait), -EINVAL);
 }
 
 static void
 test_wait_illegal_handle(int fd)
 {
-	struct local_syncobj_wait wait = { 0 };
+	struct drm_syncobj_wait wait = { 0 };
 	uint32_t handle = 0;
 
 	wait.count_handles = 1;
@@ -166,43 +166,43 @@ test_wait_illegal_handle(int fd)
 static void
 test_reset_zero_handles(int fd)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	int ret;
 
-	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array);
+	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_RESET, &array);
 	igt_assert(ret == -1 && errno ==  EINVAL);
 }
 
 static void
 test_reset_illegal_handle(int fd)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	uint32_t handle = 0;
 	int ret;
 
 	array.count_handles = 1;
 	array.handles = to_user_pointer(&handle);
-	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array);
+	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_RESET, &array);
 	igt_assert(ret == -1 && errno == ENOENT);
 }
 
 static void
 test_reset_one_illegal_handle(int fd)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	uint32_t syncobjs[3];
 	int ret;
 
-	syncobjs[0] = syncobj_create(fd, LOCAL_SYNCOBJ_CREATE_SIGNALED);
+	syncobjs[0] = syncobj_create(fd, DRM_SYNCOBJ_CREATE_SIGNALED);
 	syncobjs[1] = 0;
-	syncobjs[2] = syncobj_create(fd, LOCAL_SYNCOBJ_CREATE_SIGNALED);
+	syncobjs[2] = syncobj_create(fd, DRM_SYNCOBJ_CREATE_SIGNALED);
 
 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[0], 1, 0, 0), 0);
 	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[2], 1, 0, 0), 0);
 
 	array.count_handles = 3;
 	array.handles = to_user_pointer(syncobjs);
-	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array);
+	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_RESET, &array);
 	igt_assert(ret == -1 && errno == ENOENT);
 
 	/* Assert that we didn't actually reset anything */
@@ -216,44 +216,44 @@ test_reset_one_illegal_handle(int fd)
 static void
 test_reset_bad_pad(int fd)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	uint32_t handle = 0;
 	int ret;
 
 	array.pad = 0xdeadbeef;
 	array.count_handles = 1;
 	array.handles = to_user_pointer(&handle);
-	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_RESET, &array);
+	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_RESET, &array);
 	igt_assert(ret == -1 && errno == EINVAL);
 }
 
 static void
 test_signal_zero_handles(int fd)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	int ret;
 
-	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array);
+	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &array);
 	igt_assert(ret == -1 && errno == EINVAL);
 }
 
 static void
 test_signal_illegal_handle(int fd)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	uint32_t handle = 0;
 	int ret;
 
 	array.count_handles = 1;
 	array.handles = to_user_pointer(&handle);
-	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array);
+	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &array);
 	igt_assert(ret == -1 && errno == ENOENT);
 }
 
 static void
 test_signal_one_illegal_handle(int fd)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	uint32_t syncobjs[3];
 	int ret;
 
@@ -266,7 +266,7 @@ test_signal_one_illegal_handle(int fd)
 
 	array.count_handles = 3;
 	array.handles = to_user_pointer(syncobjs);
-	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array);
+	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &array);
 	igt_assert(ret == -1 && errno == ENOENT);
 
 	/* Assert that we didn't actually reset anything */
@@ -280,14 +280,14 @@ test_signal_one_illegal_handle(int fd)
 static void
 test_signal_bad_pad(int fd)
 {
-	struct local_syncobj_array array = { 0 };
+	struct drm_syncobj_array array = { 0 };
 	uint32_t handle = 0;
 	int ret;
 
 	array.pad = 0xdeadbeef;
 	array.count_handles = 1;
 	array.handles = to_user_pointer(&handle);
-	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_SIGNAL, &array);
+	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, &array);
 	igt_assert(ret == -1 && errno ==  EINVAL);
 }
 
@@ -304,10 +304,10 @@ flags_for_test_flags(uint32_t test_flags)
 	uint32_t flags = 0;
 
 	if (test_flags & WAIT_FOR_SUBMIT)
-		flags |= LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+		flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
 
 	if (test_flags & WAIT_ALL)
-		flags |= LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_ALL;
+		flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL;
 
 	return flags;
 }
@@ -432,7 +432,7 @@ static void
 test_reset_during_wait_for_submit(int fd)
 {
 	uint32_t syncobj = syncobj_create(fd, 0);
-	uint32_t flags = LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+	uint32_t flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
 	struct fd_handle_pair pair;
 	timer_t timer;
 
@@ -454,7 +454,7 @@ static void
 test_signal(int fd)
 {
 	uint32_t syncobj = syncobj_create(fd, 0);
-	uint32_t flags = LOCAL_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+	uint32_t flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
 
 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, 0), -EINVAL);
 	igt_assert_eq(syncobj_wait_err(fd, &syncobj, 1, 0, flags), -ETIME);
@@ -511,7 +511,7 @@ test_multi_wait(int fd, uint32_t test_flags, int expect)
 
 struct wait_thread_data {
 	int fd;
-	struct local_syncobj_wait wait;
+	struct drm_syncobj_wait wait;
 };
 
 static void *
@@ -713,7 +713,7 @@ test_wait_complex(int fd, uint32_t test_flags)
 static void
 test_wait_interrupted(int fd, uint32_t test_flags)
 {
-	struct local_syncobj_wait wait = { 0 };
+	struct drm_syncobj_wait wait = { 0 };
 	uint32_t syncobj = syncobj_create(fd, 0);
 	int timeline;
 
@@ -740,7 +740,7 @@ test_wait_interrupted(int fd, uint32_t test_flags)
 static bool
 has_syncobj_wait(int fd)
 {
-	struct local_syncobj_wait wait = { 0 };
+	struct drm_syncobj_wait wait = { 0 };
 	uint32_t handle = 0;
 	uint64_t value;
 	int ret;
@@ -753,7 +753,7 @@ has_syncobj_wait(int fd)
 	/* Try waiting for zero sync objects should fail with EINVAL */
 	wait.count_handles = 1;
 	wait.handles = to_user_pointer(&handle);
-	ret = drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_WAIT, &wait);
+	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, &wait);
 	return ret == -1 && errno == ENOENT;
 }
 
-- 
2.24.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [igt-dev] [PATCH i-g-t 02/10] drm-uapi: Update drm headers to 17cc51390c141662748dbbc2fe98f3ed10f2e13e
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 01/10] lib/syncobj: drop local declarations Lionel Landwerlin
@ 2019-11-20 21:21 ` Lionel Landwerlin
  2019-11-20 21:50   ` Chris Wilson
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 05/10] tests/i915/exec_fence: switch to internal headers Lionel Landwerlin
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-20 21:21 UTC (permalink / raw)
  To: igt-dev

  commit 17cc51390c141662748dbbc2fe98f3ed10f2e13e
  Merge: 2d0720f5a4fc b4011644b03c
  Author: Dave Airlie <airlied@redhat.com>
  Date:   Fri Nov 15 12:34:39 2019 +1000

      Merge branch 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux into drm-next

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 include/drm-uapi/amdgpu_drm.h   |  71 ++++++++++++++++++-
 include/drm-uapi/drm.h          |  39 ++++++++++
 include/drm-uapi/drm_fourcc.h   |  28 +++++++-
 include/drm-uapi/drm_mode.h     | 122 +++++++++++++++++++++++++++++++-
 include/drm-uapi/etnaviv_drm.h  |  10 ++-
 include/drm-uapi/exynos_drm.h   |   2 +-
 include/drm-uapi/msm_drm.h      |  14 ++++
 include/drm-uapi/nouveau_drm.h  |  51 +++++++++++++
 include/drm-uapi/omap_drm.h     |  18 ++---
 include/drm-uapi/panfrost_drm.h |  88 +++++++++++++++++++++++
 include/drm-uapi/v3d_drm.h      |  36 +++++++++-
 11 files changed, 459 insertions(+), 20 deletions(-)

diff --git a/include/drm-uapi/amdgpu_drm.h b/include/drm-uapi/amdgpu_drm.h
index be84e43c..bbdad866 100644
--- a/include/drm-uapi/amdgpu_drm.h
+++ b/include/drm-uapi/amdgpu_drm.h
@@ -128,6 +128,10 @@ extern "C" {
  * for the second page onward should be set to NC.
  */
 #define AMDGPU_GEM_CREATE_MQD_GFX9		(1 << 8)
+/* Flag that BO may contain sensitive data that must be wiped before
+ * releasing the memory
+ */
+#define AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE	(1 << 9)
 
 struct drm_amdgpu_gem_create_in  {
 	/** the requested memory size */
@@ -210,13 +214,19 @@ union drm_amdgpu_bo_list {
 #define AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST (1<<1)
 /* indicate some job from this context once cause gpu hang */
 #define AMDGPU_CTX_QUERY2_FLAGS_GUILTY   (1<<2)
+/* indicate some errors are detected by RAS */
+#define AMDGPU_CTX_QUERY2_FLAGS_RAS_CE   (1<<3)
+#define AMDGPU_CTX_QUERY2_FLAGS_RAS_UE   (1<<4)
 
 /* Context priority level */
 #define AMDGPU_CTX_PRIORITY_UNSET       -2048
 #define AMDGPU_CTX_PRIORITY_VERY_LOW    -1023
 #define AMDGPU_CTX_PRIORITY_LOW         -512
 #define AMDGPU_CTX_PRIORITY_NORMAL      0
-/* Selecting a priority above NORMAL requires CAP_SYS_NICE or DRM_MASTER */
+/*
+ * When used in struct drm_amdgpu_ctx_in, a priority above NORMAL requires
+ * CAP_SYS_NICE or DRM_MASTER
+*/
 #define AMDGPU_CTX_PRIORITY_HIGH        512
 #define AMDGPU_CTX_PRIORITY_VERY_HIGH   1023
 
@@ -226,6 +236,7 @@ struct drm_amdgpu_ctx_in {
 	/** For future use, no flags defined so far */
 	__u32	flags;
 	__u32	ctx_id;
+	/** AMDGPU_CTX_PRIORITY_* */
 	__s32	priority;
 };
 
@@ -272,13 +283,15 @@ union drm_amdgpu_vm {
 
 /* sched ioctl */
 #define AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE	1
+#define AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE	2
 
 struct drm_amdgpu_sched_in {
 	/* AMDGPU_SCHED_OP_* */
 	__u32	op;
 	__u32	fd;
+	/** AMDGPU_CTX_PRIORITY_* */
 	__s32	priority;
-	__u32	flags;
+	__u32   ctx_id;
 };
 
 union drm_amdgpu_sched {
@@ -487,6 +500,8 @@ struct drm_amdgpu_gem_op {
 #define AMDGPU_VM_MTYPE_CC		(3 << 5)
 /* Use UC MTYPE instead of default MTYPE */
 #define AMDGPU_VM_MTYPE_UC		(4 << 5)
+/* Use RW MTYPE instead of default MTYPE */
+#define AMDGPU_VM_MTYPE_RW		(5 << 5)
 
 struct drm_amdgpu_gem_va {
 	/** GEM object handle */
@@ -523,6 +538,9 @@ struct drm_amdgpu_gem_va {
 #define AMDGPU_CHUNK_ID_SYNCOBJ_IN      0x04
 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT     0x05
 #define AMDGPU_CHUNK_ID_BO_HANDLES      0x06
+#define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES	0x07
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT    0x08
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL  0x09
 
 struct drm_amdgpu_cs_chunk {
 	__u32		chunk_id;
@@ -565,6 +583,11 @@ union drm_amdgpu_cs {
  * caches (L2/vL1/sL1/I$). */
 #define AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE (1 << 3)
 
+/* Set GDS_COMPUTE_MAX_WAVE_ID = DEFAULT before PACKET3_INDIRECT_BUFFER.
+ * This will reset wave ID counters for the IB.
+ */
+#define AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID (1 << 4)
+
 struct drm_amdgpu_cs_chunk_ib {
 	__u32 _pad;
 	/** AMDGPU_IB_FLAG_* */
@@ -598,6 +621,12 @@ struct drm_amdgpu_cs_chunk_sem {
 	__u32 handle;
 };
 
+struct drm_amdgpu_cs_chunk_syncobj {
+       __u32 handle;
+       __u32 flags;
+       __u64 point;
+};
+
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ	0
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD	1
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD	2
@@ -673,6 +702,7 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM 0x11
 	/* Subquery id: Query DMCU firmware version */
 	#define AMDGPU_INFO_FW_DMCU		0x12
+	#define AMDGPU_INFO_FW_TA		0x13
 /* number of bytes moved for TTM migration */
 #define AMDGPU_INFO_NUM_BYTES_MOVED		0x0f
 /* the used VRAM size */
@@ -726,6 +756,37 @@ struct drm_amdgpu_cs_chunk_data {
 /* Number of VRAM page faults on CPU access. */
 #define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS	0x1E
 #define AMDGPU_INFO_VRAM_LOST_COUNTER		0x1F
+/* query ras mask of enabled features*/
+#define AMDGPU_INFO_RAS_ENABLED_FEATURES	0x20
+
+/* RAS MASK: UMC (VRAM) */
+#define AMDGPU_INFO_RAS_ENABLED_UMC			(1 << 0)
+/* RAS MASK: SDMA */
+#define AMDGPU_INFO_RAS_ENABLED_SDMA			(1 << 1)
+/* RAS MASK: GFX */
+#define AMDGPU_INFO_RAS_ENABLED_GFX			(1 << 2)
+/* RAS MASK: MMHUB */
+#define AMDGPU_INFO_RAS_ENABLED_MMHUB			(1 << 3)
+/* RAS MASK: ATHUB */
+#define AMDGPU_INFO_RAS_ENABLED_ATHUB			(1 << 4)
+/* RAS MASK: PCIE */
+#define AMDGPU_INFO_RAS_ENABLED_PCIE			(1 << 5)
+/* RAS MASK: HDP */
+#define AMDGPU_INFO_RAS_ENABLED_HDP			(1 << 6)
+/* RAS MASK: XGMI */
+#define AMDGPU_INFO_RAS_ENABLED_XGMI			(1 << 7)
+/* RAS MASK: DF */
+#define AMDGPU_INFO_RAS_ENABLED_DF			(1 << 8)
+/* RAS MASK: SMN */
+#define AMDGPU_INFO_RAS_ENABLED_SMN			(1 << 9)
+/* RAS MASK: SEM */
+#define AMDGPU_INFO_RAS_ENABLED_SEM			(1 << 10)
+/* RAS MASK: MP0 */
+#define AMDGPU_INFO_RAS_ENABLED_MP0			(1 << 11)
+/* RAS MASK: MP1 */
+#define AMDGPU_INFO_RAS_ENABLED_MP1			(1 << 12)
+/* RAS MASK: FUSE */
+#define AMDGPU_INFO_RAS_ENABLED_FUSE			(1 << 13)
 
 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT	0
 #define AMDGPU_INFO_MMR_SE_INDEX_MASK	0xff
@@ -862,6 +923,7 @@ struct drm_amdgpu_info_firmware {
 #define AMDGPU_VRAM_TYPE_HBM   6
 #define AMDGPU_VRAM_TYPE_DDR3  7
 #define AMDGPU_VRAM_TYPE_DDR4  8
+#define AMDGPU_VRAM_TYPE_GDDR6 9
 
 struct drm_amdgpu_info_device {
 	/** PCI Device ID */
@@ -941,6 +1003,10 @@ struct drm_amdgpu_info_device {
 	__u64 high_va_offset;
 	/** The maximum high virtual address */
 	__u64 high_va_max;
+	/* gfx10 pa_sc_tile_steering_override */
+	__u32 pa_sc_tile_steering_override;
+	/* disabled TCCs */
+	__u64 tcc_disabled_mask;
 };
 
 struct drm_amdgpu_info_hw_ip {
@@ -994,6 +1060,7 @@ struct drm_amdgpu_info_vce_clock_table {
 #define AMDGPU_FAMILY_CZ			135 /* Carrizo, Stoney */
 #define AMDGPU_FAMILY_AI			141 /* Vega10 */
 #define AMDGPU_FAMILY_RV			142 /* Raven */
+#define AMDGPU_FAMILY_NV			143 /* Navi10 */
 
 #if defined(__cplusplus)
 }
diff --git a/include/drm-uapi/drm.h b/include/drm-uapi/drm.h
index 85c685a2..ab940339 100644
--- a/include/drm-uapi/drm.h
+++ b/include/drm-uapi/drm.h
@@ -44,6 +44,7 @@ typedef unsigned int drm_handle_t;
 
 #else /* One of the BSDs */
 
+#include <stdint.h>
 #include <sys/ioccom.h>
 #include <sys/types.h>
 typedef int8_t   __s8;
@@ -643,6 +644,7 @@ struct drm_gem_open {
 #define DRM_CAP_PAGE_FLIP_TARGET	0x11
 #define DRM_CAP_CRTC_IN_VBLANK_EVENT	0x12
 #define DRM_CAP_SYNCOBJ		0x13
+#define DRM_CAP_SYNCOBJ_TIMELINE	0x14
 
 /** DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
@@ -729,8 +731,18 @@ struct drm_syncobj_handle {
 	__u32 pad;
 };
 
+struct drm_syncobj_transfer {
+	__u32 src_handle;
+	__u32 dst_handle;
+	__u64 src_point;
+	__u64 dst_point;
+	__u32 flags;
+	__u32 pad;
+};
+
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2) /* wait for time point to become available */
 struct drm_syncobj_wait {
 	__u64 handles;
 	/* absolute timeout */
@@ -741,12 +753,34 @@ struct drm_syncobj_wait {
 	__u32 pad;
 };
 
+struct drm_syncobj_timeline_wait {
+	__u64 handles;
+	/* wait on specific timeline point for every handles*/
+	__u64 points;
+	/* absolute timeout */
+	__s64 timeout_nsec;
+	__u32 count_handles;
+	__u32 flags;
+	__u32 first_signaled; /* only valid when not waiting all */
+	__u32 pad;
+};
+
+
 struct drm_syncobj_array {
 	__u64 handles;
 	__u32 count_handles;
 	__u32 pad;
 };
 
+#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available point on timeline syncobj */
+struct drm_syncobj_timeline_array {
+	__u64 handles;
+	__u64 points;
+	__u32 count_handles;
+	__u32 flags;
+};
+
+
 /* Query current scanout sequence number */
 struct drm_crtc_get_sequence {
 	__u32 crtc_id;		/* requested crtc_id */
@@ -903,6 +937,11 @@ extern "C" {
 #define DRM_IOCTL_MODE_GET_LEASE	DRM_IOWR(0xC8, struct drm_mode_get_lease)
 #define DRM_IOCTL_MODE_REVOKE_LEASE	DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
 
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT	DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)
+#define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
+#define DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
+
 /**
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.
diff --git a/include/drm-uapi/drm_fourcc.h b/include/drm-uapi/drm_fourcc.h
index b93eb2d4..2073420d 100644
--- a/include/drm-uapi/drm_fourcc.h
+++ b/include/drm-uapi/drm_fourcc.h
@@ -69,7 +69,7 @@ extern "C" {
 #define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
 				 ((__u32)(c) << 16) | ((__u32)(d) << 24))
 
-#define DRM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */
+#define DRM_FORMAT_BIG_ENDIAN (1U<<31) /* format is big endian instead of little endian */
 
 /* Reserve 0 for the invalid format specifier */
 #define DRM_FORMAT_INVALID	0
@@ -649,7 +649,21 @@ extern "C" {
  * Further information on the use of AFBC modifiers can be found in
  * Documentation/gpu/afbc.rst
  */
-#define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode)	fourcc_mod_code(ARM, __afbc_mode)
+
+/*
+ * The top 4 bits (out of the 56 bits alloted for specifying vendor specific
+ * modifiers) denote the category for modifiers. Currently we have only two
+ * categories of modifiers ie AFBC and MISC. We can have a maximum of sixteen
+ * different categories.
+ */
+#define DRM_FORMAT_MOD_ARM_CODE(__type, __val) \
+	fourcc_mod_code(ARM, ((__u64)(__type) << 52) | ((__val) & 0x000fffffffffffffULL))
+
+#define DRM_FORMAT_MOD_ARM_TYPE_AFBC 0x00
+#define DRM_FORMAT_MOD_ARM_TYPE_MISC 0x01
+
+#define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode) \
+	DRM_FORMAT_MOD_ARM_CODE(DRM_FORMAT_MOD_ARM_TYPE_AFBC, __afbc_mode)
 
 /*
  * AFBC superblock size
@@ -743,6 +757,16 @@ extern "C" {
  */
 #define AFBC_FORMAT_MOD_BCH     (1ULL << 11)
 
+/*
+ * Arm 16x16 Block U-Interleaved modifier
+ *
+ * This is used by Arm Mali Utgard and Midgard GPUs. It divides the image
+ * into 16x16 pixel blocks. Blocks are stored linearly in order, but pixels
+ * in the block are reordered.
+ */
+#define DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED \
+	DRM_FORMAT_MOD_ARM_CODE(DRM_FORMAT_MOD_ARM_TYPE_MISC, 1ULL)
+
 /*
  * Allwinner tiled modifier
  *
diff --git a/include/drm-uapi/drm_mode.h b/include/drm-uapi/drm_mode.h
index a439c2e6..735c8cfd 100644
--- a/include/drm-uapi/drm_mode.h
+++ b/include/drm-uapi/drm_mode.h
@@ -33,7 +33,15 @@
 extern "C" {
 #endif
 
-#define DRM_DISPLAY_INFO_LEN	32
+/**
+ * DOC: overview
+ *
+ * DRM exposes many UAPI and structure definition to have a consistent
+ * and standardized interface with user.
+ * Userspace can refer to these structure definitions and UAPI formats
+ * to communicate to driver
+ */
+
 #define DRM_CONNECTOR_NAME_LEN	32
 #define DRM_DISPLAY_MODE_LEN	32
 #define DRM_PROP_NAME_LEN	32
@@ -353,6 +361,7 @@ enum drm_mode_subconnector {
 #define DRM_MODE_CONNECTOR_DSI		16
 #define DRM_MODE_CONNECTOR_DPI		17
 #define DRM_MODE_CONNECTOR_WRITEBACK	18
+#define DRM_MODE_CONNECTOR_SPI		19
 
 struct drm_mode_get_connector {
 
@@ -622,7 +631,8 @@ struct drm_color_ctm {
 
 struct drm_color_lut {
 	/*
-	 * Data is U0.16 fixed point format.
+	 * Values are mapped linearly to 0.0 - 1.0 range, with 0x0 == 0.0 and
+	 * 0xffff == 1.0.
 	 */
 	__u16 red;
 	__u16 green;
@@ -630,6 +640,92 @@ struct drm_color_lut {
 	__u16 reserved;
 };
 
+/**
+ * struct hdr_metadata_infoframe - HDR Metadata Infoframe Data.
+ *
+ * HDR Metadata Infoframe as per CTA 861.G spec. This is expected
+ * to match exactly with the spec.
+ *
+ * Userspace is expected to pass the metadata information as per
+ * the format described in this structure.
+ */
+struct hdr_metadata_infoframe {
+	/**
+	 * @eotf: Electro-Optical Transfer Function (EOTF)
+	 * used in the stream.
+	 */
+	__u8 eotf;
+	/**
+	 * @metadata_type: Static_Metadata_Descriptor_ID.
+	 */
+	__u8 metadata_type;
+	/**
+	 * @display_primaries: Color Primaries of the Data.
+	 * These are coded as unsigned 16-bit values in units of
+	 * 0.00002, where 0x0000 represents zero and 0xC350
+	 * represents 1.0000.
+	 * @display_primaries.x: X cordinate of color primary.
+	 * @display_primaries.y: Y cordinate of color primary.
+	 */
+	struct {
+		__u16 x, y;
+		} display_primaries[3];
+	/**
+	 * @white_point: White Point of Colorspace Data.
+	 * These are coded as unsigned 16-bit values in units of
+	 * 0.00002, where 0x0000 represents zero and 0xC350
+	 * represents 1.0000.
+	 * @white_point.x: X cordinate of whitepoint of color primary.
+	 * @white_point.y: Y cordinate of whitepoint of color primary.
+	 */
+	struct {
+		__u16 x, y;
+		} white_point;
+	/**
+	 * @max_display_mastering_luminance: Max Mastering Display Luminance.
+	 * This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
+	 * where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
+	 */
+	__u16 max_display_mastering_luminance;
+	/**
+	 * @min_display_mastering_luminance: Min Mastering Display Luminance.
+	 * This value is coded as an unsigned 16-bit value in units of
+	 * 0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF
+	 * represents 6.5535 cd/m2.
+	 */
+	__u16 min_display_mastering_luminance;
+	/**
+	 * @max_cll: Max Content Light Level.
+	 * This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
+	 * where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
+	 */
+	__u16 max_cll;
+	/**
+	 * @max_fall: Max Frame Average Light Level.
+	 * This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
+	 * where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
+	 */
+	__u16 max_fall;
+};
+
+/**
+ * struct hdr_output_metadata - HDR output metadata
+ *
+ * Metadata Information to be passed from userspace
+ */
+struct hdr_output_metadata {
+	/**
+	 * @metadata_type: Static_Metadata_Descriptor_ID.
+	 */
+	__u32 metadata_type;
+	/**
+	 * @hdmi_metadata_type1: HDR Metadata Infoframe.
+	 */
+	union {
+		struct hdr_metadata_infoframe hdmi_metadata_type1;
+	};
+};
+
 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
@@ -803,6 +899,10 @@ struct drm_format_modifier {
 };
 
 /**
+ * struct drm_mode_create_blob - Create New block property
+ * @data: Pointer to data to copy.
+ * @length: Length of data to copy.
+ * @blob_id: new property ID.
  * Create a new 'blob' data property, copying length bytes from data pointer,
  * and returning new blob ID.
  */
@@ -816,6 +916,8 @@ struct drm_mode_create_blob {
 };
 
 /**
+ * struct drm_mode_destroy_blob - Destroy user blob
+ * @blob_id: blob_id to destroy
  * Destroy a user-created blob property.
  */
 struct drm_mode_destroy_blob {
@@ -823,6 +925,12 @@ struct drm_mode_destroy_blob {
 };
 
 /**
+ * struct drm_mode_create_lease - Create lease
+ * @object_ids: Pointer to array of object ids.
+ * @object_count: Number of object ids.
+ * @flags: flags for new FD.
+ * @lessee_id: unique identifier for lessee.
+ * @fd: file descriptor to new drm_master file.
  * Lease mode resources, creating another drm_master.
  */
 struct drm_mode_create_lease {
@@ -840,6 +948,10 @@ struct drm_mode_create_lease {
 };
 
 /**
+ * struct drm_mode_list_lessees - List lessees
+ * @count_lessees: Number of lessees.
+ * @pad: pad.
+ * @lessees_ptr: Pointer to lessess.
  * List lesses from a drm_master
  */
 struct drm_mode_list_lessees {
@@ -860,6 +972,10 @@ struct drm_mode_list_lessees {
 };
 
 /**
+ * struct drm_mode_get_lease - Get Lease
+ * @count_objects: Number of leased objects.
+ * @pad: pad.
+ * @objects_ptr: Pointer to objects.
  * Get leased objects
  */
 struct drm_mode_get_lease {
@@ -880,6 +996,8 @@ struct drm_mode_get_lease {
 };
 
 /**
+ * struct drm_mode_revoke_lease - Revoke lease
+ * @lessee_id: Unique ID of lessee.
  * Revoke lease
  */
 struct drm_mode_revoke_lease {
diff --git a/include/drm-uapi/etnaviv_drm.h b/include/drm-uapi/etnaviv_drm.h
index 0d5c49dc..09d0df8b 100644
--- a/include/drm-uapi/etnaviv_drm.h
+++ b/include/drm-uapi/etnaviv_drm.h
@@ -73,6 +73,7 @@ struct drm_etnaviv_timespec {
 #define ETNAVIV_PARAM_GPU_INSTRUCTION_COUNT         0x18
 #define ETNAVIV_PARAM_GPU_NUM_CONSTANTS             0x19
 #define ETNAVIV_PARAM_GPU_NUM_VARYINGS              0x1a
+#define ETNAVIV_PARAM_SOFTPIN_START_ADDR            0x1b
 
 #define ETNA_MAX_PIPES 4
 
@@ -148,6 +149,11 @@ struct drm_etnaviv_gem_submit_reloc {
  * then patching the cmdstream for this entry is skipped.  This can
  * avoid kernel needing to map/access the cmdstream bo in the common
  * case.
+ * If the submit is a softpin submit (ETNA_SUBMIT_SOFTPIN) the 'presumed'
+ * field is interpreted as the fixed location to map the bo into the gpu
+ * virtual address space. If the kernel is unable to map the buffer at
+ * this location the submit will fail. This means userspace is responsible
+ * for the whole gpu virtual address management.
  */
 #define ETNA_SUBMIT_BO_READ             0x0001
 #define ETNA_SUBMIT_BO_WRITE            0x0002
@@ -177,9 +183,11 @@ struct drm_etnaviv_gem_submit_pmr {
 #define ETNA_SUBMIT_NO_IMPLICIT         0x0001
 #define ETNA_SUBMIT_FENCE_FD_IN         0x0002
 #define ETNA_SUBMIT_FENCE_FD_OUT        0x0004
+#define ETNA_SUBMIT_SOFTPIN             0x0008
 #define ETNA_SUBMIT_FLAGS		(ETNA_SUBMIT_NO_IMPLICIT | \
 					 ETNA_SUBMIT_FENCE_FD_IN | \
-					 ETNA_SUBMIT_FENCE_FD_OUT)
+					 ETNA_SUBMIT_FENCE_FD_OUT| \
+					 ETNA_SUBMIT_SOFTPIN)
 #define ETNA_PIPE_3D      0x00
 #define ETNA_PIPE_2D      0x01
 #define ETNA_PIPE_VG      0x02
diff --git a/include/drm-uapi/exynos_drm.h b/include/drm-uapi/exynos_drm.h
index 7414cfd7..293815e3 100644
--- a/include/drm-uapi/exynos_drm.h
+++ b/include/drm-uapi/exynos_drm.h
@@ -68,7 +68,7 @@ struct drm_exynos_gem_info {
 /**
  * A structure for user connection request of virtual display.
  *
- * @connection: indicate whether doing connetion or not by user.
+ * @connection: indicate whether doing connection or not by user.
  * @extensions: if this value is 1 then the vidi driver would need additional
  *	128bytes edid data.
  * @edid: the edid data pointer from user side.
diff --git a/include/drm-uapi/msm_drm.h b/include/drm-uapi/msm_drm.h
index 91a16b33..0b85ed6a 100644
--- a/include/drm-uapi/msm_drm.h
+++ b/include/drm-uapi/msm_drm.h
@@ -74,6 +74,8 @@ struct drm_msm_timespec {
 #define MSM_PARAM_TIMESTAMP  0x05
 #define MSM_PARAM_GMEM_BASE  0x06
 #define MSM_PARAM_NR_RINGS   0x07
+#define MSM_PARAM_PP_PGTABLE 0x08  /* => 1 for per-process pagetables, else 0 */
+#define MSM_PARAM_FAULTS     0x09
 
 struct drm_msm_param {
 	__u32 pipe;           /* in, MSM_PIPE_x */
@@ -286,6 +288,16 @@ struct drm_msm_submitqueue {
 	__u32 id;      /* out, identifier */
 };
 
+#define MSM_SUBMITQUEUE_PARAM_FAULTS   0
+
+struct drm_msm_submitqueue_query {
+	__u64 data;
+	__u32 id;
+	__u32 param;
+	__u32 len;
+	__u32 pad;
+};
+
 #define DRM_MSM_GET_PARAM              0x00
 /* placeholder:
 #define DRM_MSM_SET_PARAM              0x01
@@ -302,6 +314,7 @@ struct drm_msm_submitqueue {
  */
 #define DRM_MSM_SUBMITQUEUE_NEW        0x0A
 #define DRM_MSM_SUBMITQUEUE_CLOSE      0x0B
+#define DRM_MSM_SUBMITQUEUE_QUERY      0x0C
 
 #define DRM_IOCTL_MSM_GET_PARAM        DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
 #define DRM_IOCTL_MSM_GEM_NEW          DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
@@ -313,6 +326,7 @@ struct drm_msm_submitqueue {
 #define DRM_IOCTL_MSM_GEM_MADVISE      DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise)
 #define DRM_IOCTL_MSM_SUBMITQUEUE_NEW    DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue)
 #define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE  DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_QUERY  DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_QUERY, struct drm_msm_submitqueue_query)
 
 #if defined(__cplusplus)
 }
diff --git a/include/drm-uapi/nouveau_drm.h b/include/drm-uapi/nouveau_drm.h
index 259588a4..9459a6e3 100644
--- a/include/drm-uapi/nouveau_drm.h
+++ b/include/drm-uapi/nouveau_drm.h
@@ -133,12 +133,63 @@ struct drm_nouveau_gem_cpu_fini {
 #define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC  0x05 /* deprecated */
 #define DRM_NOUVEAU_GPUOBJ_FREE        0x06 /* deprecated */
 #define DRM_NOUVEAU_NVIF               0x07
+#define DRM_NOUVEAU_SVM_INIT           0x08
+#define DRM_NOUVEAU_SVM_BIND           0x09
 #define DRM_NOUVEAU_GEM_NEW            0x40
 #define DRM_NOUVEAU_GEM_PUSHBUF        0x41
 #define DRM_NOUVEAU_GEM_CPU_PREP       0x42
 #define DRM_NOUVEAU_GEM_CPU_FINI       0x43
 #define DRM_NOUVEAU_GEM_INFO           0x44
 
+struct drm_nouveau_svm_init {
+	__u64 unmanaged_addr;
+	__u64 unmanaged_size;
+};
+
+struct drm_nouveau_svm_bind {
+	__u64 header;
+	__u64 va_start;
+	__u64 va_end;
+	__u64 npages;
+	__u64 stride;
+	__u64 result;
+	__u64 reserved0;
+	__u64 reserved1;
+};
+
+#define NOUVEAU_SVM_BIND_COMMAND_SHIFT          0
+#define NOUVEAU_SVM_BIND_COMMAND_BITS           8
+#define NOUVEAU_SVM_BIND_COMMAND_MASK           ((1 << 8) - 1)
+#define NOUVEAU_SVM_BIND_PRIORITY_SHIFT         8
+#define NOUVEAU_SVM_BIND_PRIORITY_BITS          8
+#define NOUVEAU_SVM_BIND_PRIORITY_MASK          ((1 << 8) - 1)
+#define NOUVEAU_SVM_BIND_TARGET_SHIFT           16
+#define NOUVEAU_SVM_BIND_TARGET_BITS            32
+#define NOUVEAU_SVM_BIND_TARGET_MASK            0xffffffff
+
+/*
+ * Below is use to validate ioctl argument, userspace can also use it to make
+ * sure that no bit are set beyond known fields for a given kernel version.
+ */
+#define NOUVEAU_SVM_BIND_VALID_BITS     48
+#define NOUVEAU_SVM_BIND_VALID_MASK     ((1ULL << NOUVEAU_SVM_BIND_VALID_BITS) - 1)
+
+
+/*
+ * NOUVEAU_BIND_COMMAND__MIGRATE: synchronous migrate to target memory.
+ * result: number of page successfuly migrate to the target memory.
+ */
+#define NOUVEAU_SVM_BIND_COMMAND__MIGRATE               0
+
+/*
+ * NOUVEAU_SVM_BIND_HEADER_TARGET__GPU_VRAM: target the GPU VRAM memory.
+ */
+#define NOUVEAU_SVM_BIND_TARGET__GPU_VRAM               (1UL << 31)
+
+
+#define DRM_IOCTL_NOUVEAU_SVM_INIT           DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_SVM_INIT, struct drm_nouveau_svm_init)
+#define DRM_IOCTL_NOUVEAU_SVM_BIND           DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_SVM_BIND, struct drm_nouveau_svm_bind)
+
 #define DRM_IOCTL_NOUVEAU_GEM_NEW            DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new)
 #define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF        DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf)
 #define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP       DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep)
diff --git a/include/drm-uapi/omap_drm.h b/include/drm-uapi/omap_drm.h
index 1fccffef..5a142fad 100644
--- a/include/drm-uapi/omap_drm.h
+++ b/include/drm-uapi/omap_drm.h
@@ -38,20 +38,20 @@ struct drm_omap_param {
 	__u64 value;			/* in (set_param), out (get_param) */
 };
 
-#define OMAP_BO_SCANOUT		0x00000001	/* scanout capable (phys contiguous) */
-#define OMAP_BO_CACHE_MASK	0x00000006	/* cache type mask, see cache modes */
-#define OMAP_BO_TILED_MASK	0x00000f00	/* tiled mapping mask, see tiled modes */
+/* Scanout buffer, consumable by DSS */
+#define OMAP_BO_SCANOUT		0x00000001
 
-/* cache modes */
-#define OMAP_BO_CACHED		0x00000000	/* default */
-#define OMAP_BO_WC		0x00000002	/* write-combine */
-#define OMAP_BO_UNCACHED	0x00000004	/* strongly-ordered (uncached) */
+/* Buffer CPU caching mode: cached, write-combining or uncached. */
+#define OMAP_BO_CACHED		0x00000000
+#define OMAP_BO_WC		0x00000002
+#define OMAP_BO_UNCACHED	0x00000004
+#define OMAP_BO_CACHE_MASK	0x00000006
 
-/* tiled modes */
+/* Use TILER for the buffer. The TILER container unit can be 8, 16 or 32 bits. */
 #define OMAP_BO_TILED_8		0x00000100
 #define OMAP_BO_TILED_16	0x00000200
 #define OMAP_BO_TILED_32	0x00000300
-#define OMAP_BO_TILED		(OMAP_BO_TILED_8 | OMAP_BO_TILED_16 | OMAP_BO_TILED_32)
+#define OMAP_BO_TILED_MASK	0x00000f00
 
 union omap_gem_size {
 	__u32 bytes;		/* (for non-tiled formats) */
diff --git a/include/drm-uapi/panfrost_drm.h b/include/drm-uapi/panfrost_drm.h
index a52e0283..ec19db1e 100644
--- a/include/drm-uapi/panfrost_drm.h
+++ b/include/drm-uapi/panfrost_drm.h
@@ -18,6 +18,9 @@ extern "C" {
 #define DRM_PANFROST_MMAP_BO			0x03
 #define DRM_PANFROST_GET_PARAM			0x04
 #define DRM_PANFROST_GET_BO_OFFSET		0x05
+#define DRM_PANFROST_PERFCNT_ENABLE		0x06
+#define DRM_PANFROST_PERFCNT_DUMP		0x07
+#define DRM_PANFROST_MADVISE			0x08
 
 #define DRM_IOCTL_PANFROST_SUBMIT		DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_SUBMIT, struct drm_panfrost_submit)
 #define DRM_IOCTL_PANFROST_WAIT_BO		DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_WAIT_BO, struct drm_panfrost_wait_bo)
@@ -25,6 +28,16 @@ extern "C" {
 #define DRM_IOCTL_PANFROST_MMAP_BO		DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_MMAP_BO, struct drm_panfrost_mmap_bo)
 #define DRM_IOCTL_PANFROST_GET_PARAM		DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_GET_PARAM, struct drm_panfrost_get_param)
 #define DRM_IOCTL_PANFROST_GET_BO_OFFSET	DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_GET_BO_OFFSET, struct drm_panfrost_get_bo_offset)
+#define DRM_IOCTL_PANFROST_MADVISE		DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_MADVISE, struct drm_panfrost_madvise)
+
+/*
+ * Unstable ioctl(s): only exposed when the unsafe unstable_ioctls module
+ * param is set to true.
+ * All these ioctl(s) are subject to deprecation, so please don't rely on
+ * them for anything but debugging purpose.
+ */
+#define DRM_IOCTL_PANFROST_PERFCNT_ENABLE	DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_PERFCNT_ENABLE, struct drm_panfrost_perfcnt_enable)
+#define DRM_IOCTL_PANFROST_PERFCNT_DUMP		DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_PERFCNT_DUMP, struct drm_panfrost_perfcnt_dump)
 
 #define PANFROST_JD_REQ_FS (1 << 0)
 /**
@@ -71,6 +84,9 @@ struct drm_panfrost_wait_bo {
 	__s64 timeout_ns;	/* absolute */
 };
 
+#define PANFROST_BO_NOEXEC	1
+#define PANFROST_BO_HEAP	2
+
 /**
  * struct drm_panfrost_create_bo - ioctl argument for creating Panfrost BOs.
  *
@@ -116,6 +132,45 @@ struct drm_panfrost_mmap_bo {
 
 enum drm_panfrost_param {
 	DRM_PANFROST_PARAM_GPU_PROD_ID,
+	DRM_PANFROST_PARAM_GPU_REVISION,
+	DRM_PANFROST_PARAM_SHADER_PRESENT,
+	DRM_PANFROST_PARAM_TILER_PRESENT,
+	DRM_PANFROST_PARAM_L2_PRESENT,
+	DRM_PANFROST_PARAM_STACK_PRESENT,
+	DRM_PANFROST_PARAM_AS_PRESENT,
+	DRM_PANFROST_PARAM_JS_PRESENT,
+	DRM_PANFROST_PARAM_L2_FEATURES,
+	DRM_PANFROST_PARAM_CORE_FEATURES,
+	DRM_PANFROST_PARAM_TILER_FEATURES,
+	DRM_PANFROST_PARAM_MEM_FEATURES,
+	DRM_PANFROST_PARAM_MMU_FEATURES,
+	DRM_PANFROST_PARAM_THREAD_FEATURES,
+	DRM_PANFROST_PARAM_MAX_THREADS,
+	DRM_PANFROST_PARAM_THREAD_MAX_WORKGROUP_SZ,
+	DRM_PANFROST_PARAM_THREAD_MAX_BARRIER_SZ,
+	DRM_PANFROST_PARAM_COHERENCY_FEATURES,
+	DRM_PANFROST_PARAM_TEXTURE_FEATURES0,
+	DRM_PANFROST_PARAM_TEXTURE_FEATURES1,
+	DRM_PANFROST_PARAM_TEXTURE_FEATURES2,
+	DRM_PANFROST_PARAM_TEXTURE_FEATURES3,
+	DRM_PANFROST_PARAM_JS_FEATURES0,
+	DRM_PANFROST_PARAM_JS_FEATURES1,
+	DRM_PANFROST_PARAM_JS_FEATURES2,
+	DRM_PANFROST_PARAM_JS_FEATURES3,
+	DRM_PANFROST_PARAM_JS_FEATURES4,
+	DRM_PANFROST_PARAM_JS_FEATURES5,
+	DRM_PANFROST_PARAM_JS_FEATURES6,
+	DRM_PANFROST_PARAM_JS_FEATURES7,
+	DRM_PANFROST_PARAM_JS_FEATURES8,
+	DRM_PANFROST_PARAM_JS_FEATURES9,
+	DRM_PANFROST_PARAM_JS_FEATURES10,
+	DRM_PANFROST_PARAM_JS_FEATURES11,
+	DRM_PANFROST_PARAM_JS_FEATURES12,
+	DRM_PANFROST_PARAM_JS_FEATURES13,
+	DRM_PANFROST_PARAM_JS_FEATURES14,
+	DRM_PANFROST_PARAM_JS_FEATURES15,
+	DRM_PANFROST_PARAM_NR_CORE_GROUPS,
+	DRM_PANFROST_PARAM_THREAD_TLS_ALLOC,
 };
 
 struct drm_panfrost_get_param {
@@ -135,6 +190,39 @@ struct drm_panfrost_get_bo_offset {
 	__u64 offset;
 };
 
+struct drm_panfrost_perfcnt_enable {
+	__u32 enable;
+	/*
+	 * On bifrost we have 2 sets of counters, this parameter defines the
+	 * one to track.
+	 */
+	__u32 counterset;
+};
+
+struct drm_panfrost_perfcnt_dump {
+	__u64 buf_ptr;
+};
+
+/* madvise provides a way to tell the kernel in case a buffers contents
+ * can be discarded under memory pressure, which is useful for userspace
+ * bo cache where we want to optimistically hold on to buffer allocate
+ * and potential mmap, but allow the pages to be discarded under memory
+ * pressure.
+ *
+ * Typical usage would involve madvise(DONTNEED) when buffer enters BO
+ * cache, and madvise(WILLNEED) if trying to recycle buffer from BO cache.
+ * In the WILLNEED case, 'retained' indicates to userspace whether the
+ * backing pages still exist.
+ */
+#define PANFROST_MADV_WILLNEED 0	/* backing pages are needed, status returned in 'retained' */
+#define PANFROST_MADV_DONTNEED 1	/* backing pages not needed */
+
+struct drm_panfrost_madvise {
+	__u32 handle;         /* in, GEM handle */
+	__u32 madv;           /* in, PANFROST_MADV_x */
+	__u32 retained;       /* out, whether backing store still exists */
+};
+
 #if defined(__cplusplus)
 }
 #endif
diff --git a/include/drm-uapi/v3d_drm.h b/include/drm-uapi/v3d_drm.h
index ea70669d..1ce746e2 100644
--- a/include/drm-uapi/v3d_drm.h
+++ b/include/drm-uapi/v3d_drm.h
@@ -37,6 +37,7 @@ extern "C" {
 #define DRM_V3D_GET_PARAM                         0x04
 #define DRM_V3D_GET_BO_OFFSET                     0x05
 #define DRM_V3D_SUBMIT_TFU                        0x06
+#define DRM_V3D_SUBMIT_CSD                        0x07
 
 #define DRM_IOCTL_V3D_SUBMIT_CL           DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl)
 #define DRM_IOCTL_V3D_WAIT_BO             DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo)
@@ -45,6 +46,9 @@ extern "C" {
 #define DRM_IOCTL_V3D_GET_PARAM           DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_PARAM, struct drm_v3d_get_param)
 #define DRM_IOCTL_V3D_GET_BO_OFFSET       DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_BO_OFFSET, struct drm_v3d_get_bo_offset)
 #define DRM_IOCTL_V3D_SUBMIT_TFU          DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_TFU, struct drm_v3d_submit_tfu)
+#define DRM_IOCTL_V3D_SUBMIT_CSD          DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CSD, struct drm_v3d_submit_csd)
+
+#define DRM_V3D_SUBMIT_CL_FLUSH_CACHE             0x01
 
 /**
  * struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D
@@ -59,7 +63,7 @@ extern "C" {
  * flushed by the time the render done IRQ happens, which is the
  * trigger for out_sync.  Any dirtying of cachelines by the job (only
  * possible using TMU writes) must be flushed by the caller using the
- * CL's cache flush commands.
+ * DRM_V3D_SUBMIT_CL_FLUSH_CACHE_FLAG flag.
  */
 struct drm_v3d_submit_cl {
 	/* Pointer to the binner command list.
@@ -122,8 +126,7 @@ struct drm_v3d_submit_cl {
 	/* Number of BO handles passed in (size is that times 4). */
 	__u32 bo_handle_count;
 
-	/* Pad, must be zero-filled. */
-	__u32 pad;
+	__u32 flags;
 };
 
 /**
@@ -190,6 +193,8 @@ enum drm_v3d_param {
 	DRM_V3D_PARAM_V3D_CORE0_IDENT1,
 	DRM_V3D_PARAM_V3D_CORE0_IDENT2,
 	DRM_V3D_PARAM_SUPPORTS_TFU,
+	DRM_V3D_PARAM_SUPPORTS_CSD,
+	DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH,
 };
 
 struct drm_v3d_get_param {
@@ -230,6 +235,31 @@ struct drm_v3d_submit_tfu {
 	__u32 out_sync;
 };
 
+/* Submits a compute shader for dispatch.  This job will block on any
+ * previous compute shaders submitted on this fd, and any other
+ * synchronization must be performed with in_sync/out_sync.
+ */
+struct drm_v3d_submit_csd {
+	__u32 cfg[7];
+	__u32 coef[4];
+
+	/* Pointer to a u32 array of the BOs that are referenced by the job.
+	 */
+	__u64 bo_handles;
+
+	/* Number of BO handles passed in (size is that times 4). */
+	__u32 bo_handle_count;
+
+	/* sync object to block on before running the CSD job.  Each
+	 * CSD job will execute in the order submitted to its FD.
+	 * Synchronization against rendering/TFU jobs or CSD from
+	 * other fds requires using sync objects.
+	 */
+	__u32 in_sync;
+	/* Sync object to signal when the CSD job is done. */
+	__u32 out_sync;
+};
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.24.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [igt-dev] [PATCH i-g-t 05/10] tests/i915/exec_fence: switch to internal headers
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 01/10] lib/syncobj: drop local declarations Lionel Landwerlin
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 02/10] drm-uapi: Update drm headers to 17cc51390c141662748dbbc2fe98f3ed10f2e13e Lionel Landwerlin
@ 2019-11-20 21:21 ` Lionel Landwerlin
  2019-11-20 21:51   ` Chris Wilson
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 06/10] tests/i915/exec_fence: reuse syncobj helpers Lionel Landwerlin
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-20 21:21 UTC (permalink / raw)
  To: igt-dev

Drop local defines etc..

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 tests/i915/gem_exec_fence.c | 122 ++++++++++++++++--------------------
 1 file changed, 55 insertions(+), 67 deletions(-)

diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index fbb11ab2..b8fa1a03 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -33,18 +33,6 @@
 
 IGT_TEST_DESCRIPTION("Check that execbuf waits for explicit fences");
 
-#define LOCAL_EXEC_FENCE_IN (1 << 16)
-#define LOCAL_EXEC_FENCE_OUT (1 << 17)
-#define LOCAL_EXEC_FENCE_SUBMIT (1 << 20)
-
-#define LOCAL_EXEC_FENCE_ARRAY (1 << 19)
-struct local_gem_exec_fence {
-	uint32_t handle;
-	uint32_t flags;
-#define LOCAL_EXEC_FENCE_WAIT (1 << 0)
-#define LOCAL_EXEC_FENCE_SIGNAL (1 << 1)
-};
-
 #ifndef SYNC_IOC_MERGE
 struct sync_merge_data {
 	char    name[32];
@@ -71,7 +59,7 @@ static void store(int fd, unsigned ring, int fence, uint32_t target, unsigned of
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(obj);
 	execbuf.buffer_count = 2;
-	execbuf.flags = ring | LOCAL_EXEC_FENCE_IN;
+	execbuf.flags = ring | I915_EXEC_FENCE_IN;
 	execbuf.rsvd2 = fence;
 	if (gen < 6)
 		execbuf.flags |= I915_EXEC_SECURE;
@@ -137,7 +125,7 @@ static void test_fence_busy(int fd, unsigned ring, unsigned flags)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj);
 	execbuf.buffer_count = 1;
-	execbuf.flags = ring | LOCAL_EXEC_FENCE_OUT;
+	execbuf.flags = ring | I915_EXEC_FENCE_OUT;
 
 	memset(&obj, 0, sizeof(obj));
 	obj.handle = gem_create(fd, 4096);
@@ -270,7 +258,7 @@ static void test_fence_busy_all(int fd, unsigned flags)
 
 		if ((flags & HANG) == 0)
 			igt_require(gem_engine_has_mutable_submission(fd, eb_ring(e)));
-		execbuf.flags = eb_ring(e) | LOCAL_EXEC_FENCE_OUT;
+		execbuf.flags = eb_ring(e) | I915_EXEC_FENCE_OUT;
 		execbuf.rsvd2 = -1;
 		gem_execbuf_wr(fd, &execbuf);
 		fence = execbuf.rsvd2 >> 32;
@@ -435,7 +423,7 @@ static void test_parallel(int fd, unsigned int master)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(obj);
 	execbuf.buffer_count = 2;
-	execbuf.flags = master | LOCAL_EXEC_FENCE_OUT;
+	execbuf.flags = master | I915_EXEC_FENCE_OUT;
 	if (gen < 6)
 		execbuf.flags |= I915_EXEC_SECURE;
 
@@ -508,7 +496,7 @@ static void test_parallel(int fd, unsigned int master)
 		if (eb_ring(e) == master)
 			continue;
 
-		execbuf.flags = eb_ring(e) | LOCAL_EXEC_FENCE_SUBMIT;
+		execbuf.flags = eb_ring(e) | I915_EXEC_FENCE_SUBMIT;
 		if (gen < 6)
 			execbuf.flags |= I915_EXEC_SECURE;
 
@@ -604,7 +592,7 @@ static void test_keep_in_fence(int fd, unsigned int engine, unsigned int flags)
 	struct drm_i915_gem_execbuffer2 execbuf = {
 		.buffers_ptr = to_user_pointer(&obj),
 		.buffer_count = 1,
-		.flags = engine | LOCAL_EXEC_FENCE_OUT,
+		.flags = engine | I915_EXEC_FENCE_OUT,
 	};
 	unsigned long count, last;
 	struct itimerval itv;
@@ -623,7 +611,7 @@ static void test_keep_in_fence(int fd, unsigned int engine, unsigned int flags)
 	itv.it_value.tv_usec = 10000;
 	setitimer(ITIMER_REAL, &itv, NULL);
 
-	execbuf.flags |= LOCAL_EXEC_FENCE_IN;
+	execbuf.flags |= I915_EXEC_FENCE_IN;
 	execbuf.rsvd2 = fence;
 
 	last = -1;
@@ -692,7 +680,7 @@ static void test_long_history(int fd, long ring_size, unsigned flags)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj[1]);
 	execbuf.buffer_count = 1;
-	execbuf.flags = LOCAL_EXEC_FENCE_OUT;
+	execbuf.flags = I915_EXEC_FENCE_OUT;
 
 	gem_execbuf_wr(fd, &execbuf);
 	all_fences = execbuf.rsvd2 >> 32;
@@ -708,7 +696,7 @@ static void test_long_history(int fd, long ring_size, unsigned flags)
 		for (n = 0; n < nengine; n++) {
 			struct sync_merge_data merge;
 
-			execbuf.flags = engines[n] | LOCAL_EXEC_FENCE_OUT;
+			execbuf.flags = engines[n] | I915_EXEC_FENCE_OUT;
 			if (__gem_execbuf_wr(fd, &execbuf))
 				continue;
 
@@ -742,7 +730,7 @@ static void test_long_history(int fd, long ring_size, unsigned flags)
 
 	for (s = 0; s < ring_size; s++) {
 		for (n = 0; n < nengine; n++) {
-			execbuf.flags = engines[n] | LOCAL_EXEC_FENCE_IN;
+			execbuf.flags = engines[n] | I915_EXEC_FENCE_IN;
 			if (__gem_execbuf_wr(fd, &execbuf))
 				continue;
 		}
@@ -766,7 +754,7 @@ static bool has_submit_fence(int fd)
 	int value = 0;
 
 	memset(&gp, 0, sizeof(gp));
-	gp.param = 0xdeadbeef ^ 51; /* I915_PARAM_HAS_EXEC_SUBMIT_FENCE */
+	gp.param = 0xdeadbeef ^ I915_PARAM_HAS_EXEC_SUBMIT_FENCE;
 	gp.value = &value;
 
 	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
@@ -777,7 +765,7 @@ static bool has_submit_fence(int fd)
 
 static bool has_syncobj(int fd)
 {
-	struct drm_get_cap cap = { .capability = 0x13 };
+	struct drm_get_cap cap = { .capability = DRM_CAP_SYNCOBJ };
 	ioctl(fd, DRM_IOCTL_GET_CAP, &cap);
 	return cap.value;
 }
@@ -788,7 +776,7 @@ static bool exec_has_fence_array(int fd)
 	int value = 0;
 
 	memset(&gp, 0, sizeof(gp));
-	gp.param = 49; /* I915_PARAM_HAS_EXEC_FENCE_ARRAY */
+	gp.param = I915_PARAM_HAS_EXEC_FENCE_ARRAY;
 	gp.value = &value;
 
 	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
@@ -802,7 +790,7 @@ static void test_invalid_fence_array(int fd)
 	const uint32_t bbe = MI_BATCH_BUFFER_END;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	struct drm_i915_gem_exec_object2 obj;
-	struct local_gem_exec_fence fence;
+	struct drm_i915_gem_exec_fence fence;
 	void *ptr;
 
 	/* create an otherwise valid execbuf */
@@ -814,7 +802,7 @@ static void test_invalid_fence_array(int fd)
 	execbuf.buffer_count = 1;
 	gem_execbuf(fd, &execbuf);
 
-	execbuf.flags |= LOCAL_EXEC_FENCE_ARRAY;
+	execbuf.flags |= I915_EXEC_FENCE_ARRAY;
 	gem_execbuf(fd, &execbuf);
 
 	/* Now add a few invalid fence-array pointers */
@@ -1026,7 +1014,7 @@ static void test_syncobj_unused_fence(int fd)
 	const uint32_t bbe = MI_BATCH_BUFFER_END;
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
-	struct local_gem_exec_fence fence = {
+	struct drm_i915_gem_exec_fence fence = {
 		.handle = syncobj_create(fd),
 	};
 	igt_spin_t *spin = igt_spin_new(fd);
@@ -1037,7 +1025,7 @@ static void test_syncobj_unused_fence(int fd)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj);
 	execbuf.buffer_count = 1;
-	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+	execbuf.flags = I915_EXEC_FENCE_ARRAY;
 	execbuf.cliprects_ptr = to_user_pointer(&fence);
 	execbuf.num_cliprects = 1;
 
@@ -1062,14 +1050,14 @@ static void test_syncobj_invalid_wait(int fd)
 	const uint32_t bbe = MI_BATCH_BUFFER_END;
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
-	struct local_gem_exec_fence fence = {
+	struct drm_i915_gem_exec_fence fence = {
 		.handle = syncobj_create(fd),
 	};
 
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj);
 	execbuf.buffer_count = 1;
-	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+	execbuf.flags = I915_EXEC_FENCE_ARRAY;
 	execbuf.cliprects_ptr = to_user_pointer(&fence);
 	execbuf.num_cliprects = 1;
 
@@ -1078,7 +1066,7 @@ static void test_syncobj_invalid_wait(int fd)
 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
 
 	/* waiting before the fence is set is invalid */
-	fence.flags = LOCAL_EXEC_FENCE_WAIT;
+	fence.flags = I915_EXEC_FENCE_WAIT;
 	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
 
 	gem_close(fd, obj.handle);
@@ -1090,14 +1078,14 @@ static void test_syncobj_invalid_flags(int fd)
 	const uint32_t bbe = MI_BATCH_BUFFER_END;
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
-	struct local_gem_exec_fence fence = {
+	struct drm_i915_gem_exec_fence fence = {
 		.handle = syncobj_create(fd),
 	};
 
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj);
 	execbuf.buffer_count = 1;
-	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+	execbuf.flags = I915_EXEC_FENCE_ARRAY;
 	execbuf.cliprects_ptr = to_user_pointer(&fence);
 	execbuf.num_cliprects = 1;
 
@@ -1118,7 +1106,7 @@ static void test_syncobj_signal(int fd)
 	const uint32_t bbe = MI_BATCH_BUFFER_END;
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
-	struct local_gem_exec_fence fence = {
+	struct drm_i915_gem_exec_fence fence = {
 		.handle = syncobj_create(fd),
 	};
 	igt_spin_t *spin = igt_spin_new(fd);
@@ -1128,7 +1116,7 @@ static void test_syncobj_signal(int fd)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj);
 	execbuf.buffer_count = 1;
-	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+	execbuf.flags = I915_EXEC_FENCE_ARRAY;
 	execbuf.cliprects_ptr = to_user_pointer(&fence);
 	execbuf.num_cliprects = 1;
 
@@ -1136,7 +1124,7 @@ static void test_syncobj_signal(int fd)
 	obj.handle = gem_create(fd, 4096);
 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
 
-	fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
+	fence.flags = I915_EXEC_FENCE_SIGNAL;
 	gem_execbuf(fd, &execbuf);
 
 	igt_assert(gem_bo_busy(fd, obj.handle));
@@ -1157,7 +1145,7 @@ static void test_syncobj_wait(int fd)
 	const uint32_t bbe = MI_BATCH_BUFFER_END;
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
-	struct local_gem_exec_fence fence = {
+	struct drm_i915_gem_exec_fence fence = {
 		.handle = syncobj_create(fd),
 	};
 	igt_spin_t *spin;
@@ -1181,10 +1169,10 @@ static void test_syncobj_wait(int fd)
 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
 
 	/* Queue a signaler from the blocked engine */
-	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+	execbuf.flags = I915_EXEC_FENCE_ARRAY;
 	execbuf.cliprects_ptr = to_user_pointer(&fence);
 	execbuf.num_cliprects = 1;
-	fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
+	fence.flags = I915_EXEC_FENCE_SIGNAL;
 	gem_execbuf(fd, &execbuf);
 	igt_assert(gem_bo_busy(fd, spin->handle));
 
@@ -1209,10 +1197,10 @@ static void test_syncobj_wait(int fd)
 		igt_assert(gem_bo_busy(fd, spin->handle));
 
 		/* Now wait upon the blocked engine */
-		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY | eb_ring(e);
+		execbuf.flags = I915_EXEC_FENCE_ARRAY | eb_ring(e);
 		execbuf.cliprects_ptr = to_user_pointer(&fence);
 		execbuf.num_cliprects = 1;
-		fence.flags = LOCAL_EXEC_FENCE_WAIT;
+		fence.flags = I915_EXEC_FENCE_WAIT;
 		gem_execbuf(fd, &execbuf);
 
 		igt_assert(gem_bo_busy(fd, obj.handle));
@@ -1236,7 +1224,7 @@ static void test_syncobj_export(int fd)
 	const uint32_t bbe = MI_BATCH_BUFFER_END;
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
-	struct local_gem_exec_fence fence = {
+	struct drm_i915_gem_exec_fence fence = {
 		.handle = syncobj_create(fd),
 	};
 	int export[2];
@@ -1253,7 +1241,7 @@ static void test_syncobj_export(int fd)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj);
 	execbuf.buffer_count = 1;
-	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+	execbuf.flags = I915_EXEC_FENCE_ARRAY;
 	execbuf.cliprects_ptr = to_user_pointer(&fence);
 	execbuf.num_cliprects = 1;
 
@@ -1261,7 +1249,7 @@ static void test_syncobj_export(int fd)
 	obj.handle = gem_create(fd, 4096);
 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
 
-	fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
+	fence.flags = I915_EXEC_FENCE_SIGNAL;
 	gem_execbuf(fd, &execbuf);
 
 	igt_assert(syncobj_busy(fd, fence.handle));
@@ -1296,7 +1284,7 @@ static void test_syncobj_repeat(int fd)
 	const unsigned nfences = 4096;
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
-	struct local_gem_exec_fence *fence;
+	struct drm_i915_gem_exec_fence *fence;
 	int export;
 	igt_spin_t *spin = igt_spin_new(fd);
 
@@ -1311,7 +1299,7 @@ static void test_syncobj_repeat(int fd)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj);
 	execbuf.buffer_count = 1;
-	execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+	execbuf.flags = I915_EXEC_FENCE_ARRAY;
 	execbuf.cliprects_ptr = to_user_pointer(fence);
 	execbuf.num_cliprects = nfences;
 
@@ -1320,13 +1308,13 @@ static void test_syncobj_repeat(int fd)
 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
 
 	for (int i = 0; i < nfences; i++)
-		fence[i].flags = LOCAL_EXEC_FENCE_SIGNAL;
+		fence[i].flags = I915_EXEC_FENCE_SIGNAL;
 
 	gem_execbuf(fd, &execbuf);
 
 	for (int i = 0; i < nfences; i++) {
 		igt_assert(syncobj_busy(fd, fence[i].handle));
-		fence[i].flags |= LOCAL_EXEC_FENCE_WAIT;
+		fence[i].flags |= I915_EXEC_FENCE_WAIT;
 	}
 	igt_assert(gem_bo_busy(fd, obj.handle));
 
@@ -1364,7 +1352,7 @@ static void test_syncobj_import(int fd)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj);
 	execbuf.buffer_count = 1;
-	execbuf.flags = LOCAL_EXEC_FENCE_OUT;
+	execbuf.flags = I915_EXEC_FENCE_OUT;
 	execbuf.rsvd2 = -1;
 
 	memset(&obj, 0, sizeof(obj));
@@ -1409,7 +1397,7 @@ static void test_syncobj_channel(int fd)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = to_user_pointer(&obj);
 	execbuf.buffer_count = 1;
-	execbuf.flags = LOCAL_EXEC_FENCE_OUT;
+	execbuf.flags = I915_EXEC_FENCE_OUT;
 	execbuf.rsvd2 = -1;
 
 	memset(&obj, 0, sizeof(obj));
@@ -1417,15 +1405,15 @@ static void test_syncobj_channel(int fd)
 	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
 
 	for (int i = 0; i < ARRAY_SIZE(syncobj); i++) {
-		struct local_gem_exec_fence fence;
+		struct drm_i915_gem_exec_fence fence;
 
-		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+		execbuf.flags = I915_EXEC_FENCE_ARRAY;
 		execbuf.cliprects_ptr = to_user_pointer(&fence);
 		execbuf.num_cliprects = 1;
 
 		/* Create a primed fence */
 		fence.handle = syncobj_create(fd);
-		fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
+		fence.flags = I915_EXEC_FENCE_SIGNAL;
 
 		gem_execbuf(fd, &execbuf);
 
@@ -1434,21 +1422,21 @@ static void test_syncobj_channel(int fd)
 
 	/* Two processes in ping-pong unison (pipe), one out of sync */
 	igt_fork(child, 1) {
-		struct local_gem_exec_fence fence[3];
+		struct drm_i915_gem_exec_fence fence[3];
 		unsigned long count;
 
-		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+		execbuf.flags = I915_EXEC_FENCE_ARRAY;
 		execbuf.cliprects_ptr = to_user_pointer(fence);
 		execbuf.num_cliprects = 3;
 
 		fence[0].handle = syncobj[0];
-		fence[0].flags = LOCAL_EXEC_FENCE_SIGNAL;
+		fence[0].flags = I915_EXEC_FENCE_SIGNAL;
 
 		fence[1].handle = syncobj[1];
-		fence[1].flags = LOCAL_EXEC_FENCE_WAIT;
+		fence[1].flags = I915_EXEC_FENCE_WAIT;
 
 		fence[2].handle = syncobj[2];
-		fence[2].flags = LOCAL_EXEC_FENCE_WAIT;
+		fence[2].flags = I915_EXEC_FENCE_WAIT;
 
 		count = 0;
 		while (!*(volatile unsigned *)control) {
@@ -1459,21 +1447,21 @@ static void test_syncobj_channel(int fd)
 		control[1] = count;
 	}
 	igt_fork(child, 1) {
-		struct local_gem_exec_fence fence[3];
+		struct drm_i915_gem_exec_fence fence[3];
 		unsigned long count;
 
-		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+		execbuf.flags = I915_EXEC_FENCE_ARRAY;
 		execbuf.cliprects_ptr = to_user_pointer(fence);
 		execbuf.num_cliprects = 3;
 
 		fence[0].handle = syncobj[0];
-		fence[0].flags = LOCAL_EXEC_FENCE_WAIT;
+		fence[0].flags = I915_EXEC_FENCE_WAIT;
 
 		fence[1].handle = syncobj[1];
-		fence[1].flags = LOCAL_EXEC_FENCE_SIGNAL;
+		fence[1].flags = I915_EXEC_FENCE_SIGNAL;
 
 		fence[2].handle = syncobj[2];
-		fence[2].flags = LOCAL_EXEC_FENCE_WAIT;
+		fence[2].flags = I915_EXEC_FENCE_WAIT;
 
 		count = 0;
 		while (!*(volatile unsigned *)control) {
@@ -1483,15 +1471,15 @@ static void test_syncobj_channel(int fd)
 		control[2] = count;
 	}
 	igt_fork(child, 1) {
-		struct local_gem_exec_fence fence;
+		struct drm_i915_gem_exec_fence fence;
 		unsigned long count;
 
-		execbuf.flags = LOCAL_EXEC_FENCE_ARRAY;
+		execbuf.flags = I915_EXEC_FENCE_ARRAY;
 		execbuf.cliprects_ptr = to_user_pointer(&fence);
 		execbuf.num_cliprects = 1;
 
 		fence.handle = syncobj[2];
-		fence.flags = LOCAL_EXEC_FENCE_SIGNAL;
+		fence.flags = I915_EXEC_FENCE_SIGNAL;
 
 		count = 0;
 		while (!*(volatile unsigned *)control) {
-- 
2.24.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [igt-dev] [PATCH i-g-t 06/10] tests/i915/exec_fence: reuse syncobj helpers
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
                   ` (2 preceding siblings ...)
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 05/10] tests/i915/exec_fence: switch to internal headers Lionel Landwerlin
@ 2019-11-20 21:21 ` Lionel Landwerlin
  2019-11-20 21:52   ` Chris Wilson
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 07/10] include: bump drm headers for i915 timeline semaphores Lionel Landwerlin
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-20 21:21 UTC (permalink / raw)
  To: igt-dev

v2: Fix mistake in syncobj_busy() (Lionel)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 tests/i915/gem_exec_fence.c | 182 ++++--------------------------------
 1 file changed, 20 insertions(+), 162 deletions(-)

diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index b8fa1a03..a9e29889 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -22,6 +22,7 @@
  */
 
 #include "igt.h"
+#include "igt_syncobj.h"
 #include "igt_sysfs.h"
 #include "igt_vgem.h"
 #include "sw_sync.h"
@@ -833,168 +834,24 @@ static void test_invalid_fence_array(int fd)
 	munmap(ptr, 4096);
 }
 
-static uint32_t __syncobj_create(int fd)
-{
-	struct local_syncobj_create {
-		uint32_t handle, flags;
-	} arg;
-#define LOCAL_IOCTL_SYNCOBJ_CREATE        DRM_IOWR(0xBF, struct local_syncobj_create)
-
-	memset(&arg, 0, sizeof(arg));
-	igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_CREATE, &arg);
-
-	return arg.handle;
-}
-
-static uint32_t syncobj_create(int fd)
-{
-	uint32_t ret;
-
-	igt_assert_neq((ret = __syncobj_create(fd)), 0);
-
-	return ret;
-}
-
-static int __syncobj_destroy(int fd, uint32_t handle)
-{
-	struct local_syncobj_destroy {
-		uint32_t handle, flags;
-	} arg;
-#define LOCAL_IOCTL_SYNCOBJ_DESTROY        DRM_IOWR(0xC0, struct local_syncobj_destroy)
-	int err = 0;
-
-	memset(&arg, 0, sizeof(arg));
-	arg.handle = handle;
-	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_DESTROY, &arg))
-		err = -errno;
-
-	errno = 0;
-	return err;
-}
-
-static void syncobj_destroy(int fd, uint32_t handle)
-{
-	igt_assert_eq(__syncobj_destroy(fd, handle), 0);
-}
-
 static int __syncobj_to_sync_file(int fd, uint32_t handle)
 {
-	struct local_syncobj_handle {
-		uint32_t handle;
-		uint32_t flags;
-		int32_t fd;
-		uint32_t pad;
-	} arg;
-#define LOCAL_IOCTL_SYNCOBJ_HANDLE_TO_FD  DRM_IOWR(0xC1, struct local_syncobj_handle)
-
-	memset(&arg, 0, sizeof(arg));
-	arg.handle = handle;
-	arg.flags = 1 << 0; /* EXPORT_SYNC_FILE */
-	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_HANDLE_TO_FD, &arg))
-		arg.fd = -errno;
-
-	errno = 0;
-	return arg.fd;
-}
-
-static int syncobj_to_sync_file(int fd, uint32_t handle)
-{
-	int ret;
-
-	igt_assert_lte(0, (ret = __syncobj_to_sync_file(fd, handle)));
-
-	return ret;
-}
-
-static int __syncobj_from_sync_file(int fd, uint32_t handle, int sf)
-{
-	struct local_syncobj_handle {
-		uint32_t handle;
-		uint32_t flags;
-		int32_t fd;
-		uint32_t pad;
-	} arg;
-#define LOCAL_IOCTL_SYNCOBJ_FD_TO_HANDLE  DRM_IOWR(0xC2, struct local_syncobj_handle)
-	int err = 0;
-
-	memset(&arg, 0, sizeof(arg));
-	arg.handle = handle;
-	arg.fd = sf;
-	arg.flags = 1 << 0; /* IMPORT_SYNC_FILE */
-	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_FD_TO_HANDLE, &arg))
-		err = -errno;
-
-	errno = 0;
-	return err;
-}
-
-static void syncobj_from_sync_file(int fd, uint32_t handle, int sf)
-{
-	igt_assert_eq(__syncobj_from_sync_file(fd, handle, sf), 0);
-}
-
-static int __syncobj_export(int fd, uint32_t handle, int *syncobj)
-{
-	struct local_syncobj_handle {
-		uint32_t handle;
-		uint32_t flags;
-		int32_t fd;
-		uint32_t pad;
-	} arg;
-	int err;
-
-	memset(&arg, 0, sizeof(arg));
-	arg.handle = handle;
-
-	err = 0;
-	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_HANDLE_TO_FD, &arg))
-		err = -errno;
+	struct drm_syncobj_handle arg = {
+		.handle = handle,
+		.flags = DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE,
+	};
 
-	errno = 0;
-	*syncobj = arg.fd;
-	return err;
+	return __syncobj_handle_to_fd(fd, &arg);
 }
 
 static int syncobj_export(int fd, uint32_t handle)
 {
-	int syncobj;
-
-	igt_assert_eq(__syncobj_export(fd, handle, &syncobj), 0);
-
-	return syncobj;
-}
-
-static int __syncobj_import(int fd, int syncobj, uint32_t *handle)
-{
-	struct local_syncobj_handle {
-		uint32_t handle;
-		uint32_t flags;
-		int32_t fd;
-		uint32_t pad;
-	} arg;
-#define LOCAL_IOCTL_SYNCOBJ_FD_TO_HANDLE  DRM_IOWR(0xC2, struct local_syncobj_handle)
-	int err;
-
-	memset(&arg, 0, sizeof(arg));
-	arg.fd = syncobj;
-
-	err = 0;
-	if (igt_ioctl(fd, LOCAL_IOCTL_SYNCOBJ_FD_TO_HANDLE, &arg))
-		err = -errno;
-
-	errno = 0;
-	*handle = arg.handle;
-	return err;
+	return syncobj_handle_to_fd(fd, handle, 0);
 }
 
 static uint32_t syncobj_import(int fd, int syncobj)
 {
-	uint32_t handle;
-
-	igt_assert_eq(__syncobj_import(fd, syncobj, &handle), 0);
-
-
-	return handle;
+	return syncobj_fd_to_handle(fd, syncobj, 0);
 }
 
 static bool syncobj_busy(int fd, uint32_t handle)
@@ -1002,7 +859,8 @@ static bool syncobj_busy(int fd, uint32_t handle)
 	bool result;
 	int sf;
 
-	sf = syncobj_to_sync_file(fd, handle);
+	sf = syncobj_handle_to_fd(fd, handle,
+				  DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE);
 	result = poll(&(struct pollfd){sf, POLLIN}, 1, 0) == 0;
 	close(sf);
 
@@ -1015,7 +873,7 @@ static void test_syncobj_unused_fence(int fd)
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	struct drm_i915_gem_exec_fence fence = {
-		.handle = syncobj_create(fd),
+		.handle = syncobj_create(fd, 0),
 	};
 	igt_spin_t *spin = igt_spin_new(fd);
 
@@ -1051,7 +909,7 @@ static void test_syncobj_invalid_wait(int fd)
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	struct drm_i915_gem_exec_fence fence = {
-		.handle = syncobj_create(fd),
+		.handle = syncobj_create(fd, 0),
 	};
 
 	memset(&execbuf, 0, sizeof(execbuf));
@@ -1079,7 +937,7 @@ static void test_syncobj_invalid_flags(int fd)
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	struct drm_i915_gem_exec_fence fence = {
-		.handle = syncobj_create(fd),
+		.handle = syncobj_create(fd, 0),
 	};
 
 	memset(&execbuf, 0, sizeof(execbuf));
@@ -1107,7 +965,7 @@ static void test_syncobj_signal(int fd)
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	struct drm_i915_gem_exec_fence fence = {
-		.handle = syncobj_create(fd),
+		.handle = syncobj_create(fd, 0),
 	};
 	igt_spin_t *spin = igt_spin_new(fd);
 
@@ -1146,7 +1004,7 @@ static void test_syncobj_wait(int fd)
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	struct drm_i915_gem_exec_fence fence = {
-		.handle = syncobj_create(fd),
+		.handle = syncobj_create(fd, 0),
 	};
 	igt_spin_t *spin;
 	unsigned handle[16];
@@ -1225,7 +1083,7 @@ static void test_syncobj_export(int fd)
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	struct drm_i915_gem_exec_fence fence = {
-		.handle = syncobj_create(fd),
+		.handle = syncobj_create(fd, 0),
 	};
 	int export[2];
 	igt_spin_t *spin = igt_spin_new(fd);
@@ -1290,7 +1148,7 @@ static void test_syncobj_repeat(int fd)
 
 	/* Check that we can wait on the same fence multiple times */
 	fence = calloc(nfences, sizeof(*fence));
-	fence->handle = syncobj_create(fd);
+	fence->handle = syncobj_create(fd, 0);
 	export = syncobj_export(fd, fence->handle);
 	for (int i = 1; i < nfences; i++)
 		fence[i].handle = syncobj_import(fd, export);
@@ -1342,7 +1200,7 @@ static void test_syncobj_import(int fd)
 	struct drm_i915_gem_exec_object2 obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	igt_spin_t *spin = igt_spin_new(fd);
-	uint32_t sync = syncobj_create(fd);
+	uint32_t sync = syncobj_create(fd, 0);
 	int fence;
 
 	/* Check that we can create a syncobj from an explicit fence (which
@@ -1363,7 +1221,7 @@ static void test_syncobj_import(int fd)
 
 	fence = execbuf.rsvd2 >> 32;
 	igt_assert(fence_busy(fence));
-	syncobj_from_sync_file(fd, sync, fence);
+	syncobj_import_sync_file(fd, sync, fence);
 	close(fence);
 
 	igt_assert(gem_bo_busy(fd, obj.handle));
@@ -1412,7 +1270,7 @@ static void test_syncobj_channel(int fd)
 		execbuf.num_cliprects = 1;
 
 		/* Create a primed fence */
-		fence.handle = syncobj_create(fd);
+		fence.handle = syncobj_create(fd, 0);
 		fence.flags = I915_EXEC_FENCE_SIGNAL;
 
 		gem_execbuf(fd, &execbuf);
-- 
2.24.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [igt-dev] [PATCH i-g-t 07/10] include: bump drm headers for i915 timeline semaphores
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
                   ` (3 preceding siblings ...)
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 06/10] tests/i915/exec_fence: reuse syncobj helpers Lionel Landwerlin
@ 2019-11-20 21:21 ` Lionel Landwerlin
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 08/10] tests/i915/exec_fence: add timeline fence tests Lionel Landwerlin
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-20 21:21 UTC (permalink / raw)
  To: igt-dev

Commit to be update with proper drm-next reference once merged.
---
 include/drm-uapi/drm.h      | 17 ++++++++++
 include/drm-uapi/i915_drm.h | 64 +++++++++++++++++++++++++++++++++++--
 2 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/include/drm-uapi/drm.h b/include/drm-uapi/drm.h
index ab940339..5a2f7f7e 100644
--- a/include/drm-uapi/drm.h
+++ b/include/drm-uapi/drm.h
@@ -780,6 +780,22 @@ struct drm_syncobj_timeline_array {
 	__u32 flags;
 };
 
+struct drm_syncobj_binary_array {
+	/* A pointer to an array of u32 syncobj handles. */
+	__u64 handles;
+	/* A pointer to an array of u32 access flags for each handle. */
+	__u64 access_flags;
+	/* The binary value of a syncobj is read before it is incremented. */
+#define DRM_SYNCOBJ_BINARY_VALUE_READ (1u << 0)
+#define DRM_SYNCOBJ_BINARY_VALUE_INC  (1u << 1)
+	/* A pointer to an array of u64 values written to by the kernel if the
+	 * handle is flagged for reading.
+	 */
+	__u64 values;
+	/* The length of the 3 arrays above. */
+	__u32 count_handles;
+	__u32 pad;
+};
 
 /* Query current scanout sequence number */
 struct drm_crtc_get_sequence {
@@ -941,6 +957,7 @@ extern "C" {
 #define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
 #define DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
 #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
+#define DRM_IOCTL_SYNCOBJ_BINARY	DRM_IOWR(0xCE, struct drm_syncobj_binary_array)
 
 /**
  * Device specific ioctls should only be in their respective headers
diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index ab899abb..4ac9d735 100644
--- a/include/drm-uapi/i915_drm.h
+++ b/include/drm-uapi/i915_drm.h
@@ -618,6 +618,12 @@ typedef struct drm_i915_irq_wait {
  */
 #define I915_PARAM_PERF_REVISION	54
 
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
+ * timeline syncobj through drm_i915_gem_execbuf_ext_timeline_fences. See
+ * I915_EXEC_USE_EXTENSIONS.
+ */
+#define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
+
 /* Must be kept compact -- no holes and well documented */
 
 typedef struct drm_i915_getparam {
@@ -1014,6 +1020,42 @@ struct drm_i915_gem_exec_fence {
 	__u32 flags;
 };
 
+enum drm_i915_gem_execbuffer_ext {
+	/**
+	 * See drm_i915_gem_execbuf_ext_timeline_fences.
+	 */
+	DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES = 1,
+
+	DRM_I915_GEM_EXECBUFFER_EXT_MAX /* non-ABI */
+};
+
+/**
+ * This structure describes an array of drm_syncobj and associated points for
+ * timeline variants of drm_syncobj. It is invalid to append this structure to
+ * the execbuf if I915_EXEC_FENCE_ARRAY is set.
+ */
+struct drm_i915_gem_execbuffer_ext_timeline_fences {
+	struct i915_user_extension base;
+
+	/**
+	 * Number of element in the handles_ptr & value_ptr arrays.
+	 */
+	__u64 fence_count;
+
+	/**
+	 * Pointer to an array of struct drm_i915_gem_exec_fence of length
+	 * fence_count.
+	 */
+	__u64 handles_ptr;
+
+	/**
+	 * Pointer to an array of u64 values of length fence_count. Values
+	 * must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
+	 * drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+	 */
+	__u64 values_ptr;
+};
+
 struct drm_i915_gem_execbuffer2 {
 	/**
 	 * List of gem_exec_object2 structs
@@ -1030,8 +1072,15 @@ struct drm_i915_gem_execbuffer2 {
 	__u32 num_cliprects;
 	/**
 	 * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
-	 * is not set.  If I915_EXEC_FENCE_ARRAY is set, then this is a
-	 * struct drm_i915_gem_exec_fence *fences.
+	 * & I915_EXEC_USE_EXTENSIONS are not set.
+	 *
+	 * If I915_EXEC_FENCE_ARRAY is set, then this is a pointer to an array
+	 * of struct drm_i915_gem_exec_fence and num_cliprects is the length
+	 * of the array.
+	 *
+	 * If I915_EXEC_USE_EXTENSIONS is set, then this is a pointer to a
+	 * single struct drm_i915_gem_base_execbuffer_ext and num_cliprects is
+	 * 0.
 	 */
 	__u64 cliprects_ptr;
 #define I915_EXEC_RING_MASK              (0x3f)
@@ -1149,7 +1198,16 @@ struct drm_i915_gem_execbuffer2 {
  */
 #define I915_EXEC_FENCE_SUBMIT		(1 << 20)
 
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SUBMIT << 1))
+/*
+ * Setting I915_EXEC_USE_EXTENSIONS implies that
+ * drm_i915_gem_execbuffer2.cliprects_ptr is treated as a pointer to an linked
+ * list of i915_user_extension. Each i915_user_extension node is the base of a
+ * larger structure. The list of supported structures are listed in the
+ * drm_i915_gem_execbuffer_ext enum.
+ */
+#define I915_EXEC_USE_EXTENSIONS	(1 << 21)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_USE_EXTENSIONS<<1))
 
 #define I915_EXEC_CONTEXT_ID_MASK	(0xffffffff)
 #define i915_execbuffer2_set_context_id(eb2, context) \
-- 
2.24.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [igt-dev] [PATCH i-g-t 08/10] tests/i915/exec_fence: add timeline fence tests
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
                   ` (4 preceding siblings ...)
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 07/10] include: bump drm headers for i915 timeline semaphores Lionel Landwerlin
@ 2019-11-20 21:21 ` Lionel Landwerlin
  2019-11-20 21:40   ` Chris Wilson
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 09/10] lib/i915: add mmio base for engines Lionel Landwerlin
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-20 21:21 UTC (permalink / raw)
  To: igt-dev

We can now give a tuple (handle, point_value) for timeline semaphores.

v2: Fix up syncobj-timeline-repeat test (Lionel)
    Update following kernel rename

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 tests/i915/gem_exec_fence.c | 643 ++++++++++++++++++++++++++++++++++++
 1 file changed, 643 insertions(+)

diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index a9e29889..b38d19bf 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -1362,6 +1362,605 @@ static void test_syncobj_channel(int fd)
 		syncobj_destroy(fd, syncobj[i]);
 }
 
+static bool has_syncobj_timeline(int fd)
+{
+	struct drm_get_cap cap = { .capability = DRM_CAP_SYNCOBJ_TIMELINE };
+	ioctl(fd, DRM_IOCTL_GET_CAP, &cap);
+	return cap.value;
+}
+
+static bool exec_has_timeline_fences(int fd)
+{
+	struct drm_i915_getparam gp;
+	int value = 0;
+
+	memset(&gp, 0, sizeof(gp));
+	gp.param = I915_PARAM_HAS_EXEC_TIMELINE_FENCES;
+	gp.value = &value;
+
+	ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
+	errno = 0;
+
+	return value;
+}
+
+static const char *test_invalid_timeline_fence_array_desc =
+	"Verifies invalid execbuf parameters in"
+	" drm_i915_gem_execbuffer_ext_timeline_fences are rejected";
+static void test_invalid_timeline_fence_array(int fd)
+{
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+	struct drm_i915_gem_exec_fence fence;
+	uint64_t value;
+	void *ptr;
+
+	/* create an otherwise valid execbuf */
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	gem_execbuf(fd, &execbuf);
+
+	/* Invalid num_cliprects value */
+	execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+	execbuf.num_cliprects = 1;
+	execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+	fence.handle = syncobj_create(fd, 0);
+	fence.flags = I915_EXEC_FENCE_SIGNAL;
+	value = 1;
+
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+
+	/* Invalid fence array & i915 ext */
+	execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+	execbuf.num_cliprects = 0;
+	execbuf.flags = I915_EXEC_FENCE_ARRAY | I915_EXEC_USE_EXTENSIONS;
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+	syncobj_create(fd, fence.handle);
+
+	execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+
+	/* Invalid handles_ptr */
+	value = 1;
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = -1;
+	timeline_fences.values_ptr = to_user_pointer(&value);
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
+
+	/* Invalid values_ptr */
+	value = 1;
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = -1;
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
+
+	/* Invalid syncobj handle */
+	memset(&fence, 0, sizeof(fence));
+	fence.handle = 0;
+	fence.flags = I915_EXEC_FENCE_WAIT;
+	value = 1;
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+	/* Invalid syncobj timeline point */
+	memset(&fence, 0, sizeof(fence));
+	fence.handle = syncobj_create(fd, 0);
+	fence.flags = I915_EXEC_FENCE_WAIT;
+	value = 1;
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+	syncobj_destroy(fd, fence.handle);
+
+	/* Invalid handles_ptr */
+	ptr = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+	igt_assert(ptr != MAP_FAILED);
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(ptr);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+	do_or_die(mprotect(ptr, 4096, PROT_READ));
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+	do_or_die(mprotect(ptr, 4096, PROT_NONE));
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
+
+	munmap(ptr, 4096);
+
+	/* Invalid values_ptr */
+	ptr = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+	igt_assert(ptr != MAP_FAILED);
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(ptr);
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+	do_or_die(mprotect(ptr, 4096, PROT_READ));
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+	do_or_die(mprotect(ptr, 4096, PROT_NONE));
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
+
+	munmap(ptr, 4096);
+}
+
+static const char *test_syncobj_timeline_unused_fence_desc =
+	"Verifies that a timeline syncobj passed into"
+	" drm_i915_gem_execbuffer_ext_timeline_fences but with no signal/wait"
+	" flag is left untouched";
+static void test_syncobj_timeline_unused_fence(int fd)
+{
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+	struct drm_i915_gem_exec_fence fence = {
+		.handle = syncobj_create(fd, 0),
+	};
+	igt_spin_t *spin = igt_spin_new(fd);
+	uint64_t value = 1;
+
+	/* sanity check our syncobj_to_sync_file interface */
+	igt_assert_eq(__syncobj_to_sync_file(fd, 0), -ENOENT);
+
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+	execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+	execbuf.num_cliprects = 0;
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+	gem_execbuf(fd, &execbuf);
+
+	/* no flags, the fence isn't created */
+	igt_assert_eq(__syncobj_to_sync_file(fd, fence.handle), -EINVAL);
+	igt_assert(gem_bo_busy(fd, obj.handle));
+
+	gem_close(fd, obj.handle);
+	syncobj_destroy(fd, fence.handle);
+
+	igt_spin_free(fd, spin);
+}
+
+static const char *test_syncobj_timeline_invalid_wait_desc =
+	"Verifies that submitting an execbuf with a wait on a timeline syncobj"
+	" point that does not exists is rejected";
+static void test_syncobj_timeline_invalid_wait(int fd)
+{
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+	struct drm_i915_gem_exec_fence fence = {
+		.handle = syncobj_create(fd, 0),
+	};
+	uint64_t value = 1;
+
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+	execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+	execbuf.num_cliprects = 0;
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+	/* waiting before the fence point 1 is set is invalid */
+	fence.flags = I915_EXEC_FENCE_WAIT;
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+	/* Now set point 1. */
+	fence.flags = I915_EXEC_FENCE_SIGNAL;
+	gem_execbuf(fd, &execbuf);
+
+	/* waiting before the fence point 2 is set is invalid */
+	value = 2;
+	fence.flags = I915_EXEC_FENCE_WAIT;
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+	gem_close(fd, obj.handle);
+	syncobj_destroy(fd, fence.handle);
+}
+
+static const char *test_syncobj_timeline_invalid_flags_desc =
+	"Verifies that invalid fence flags in"
+	" drm_i915_gem_execbuffer_ext_timeline_fences are rejected";
+static void test_syncobj_timeline_invalid_flags(int fd)
+{
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+	struct drm_i915_gem_exec_fence fence = {
+		.handle = syncobj_create(fd, 0),
+	};
+	uint64_t value = 1;
+
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+	execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+	execbuf.num_cliprects = 0;
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+	/* set all flags to hit an invalid one */
+	fence.flags = ~0;
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+	gem_close(fd, obj.handle);
+	syncobj_destroy(fd, fence.handle);
+}
+
+static const char *test_syncobj_timeline_signal_desc =
+	"Verifies proper signaling of a timeline syncobj through execbuf";
+static void test_syncobj_timeline_signal(int fd)
+{
+	const uint32_t bbe = MI_BATCH_BUFFER_END;
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+	struct drm_i915_gem_exec_fence fence = {
+		.handle = syncobj_create(fd, 0),
+	};
+	uint64_t value = 42, query_value;
+	igt_spin_t *spin = igt_spin_new(fd);
+
+	/* Check that the syncobj is signaled only when our request/fence is */
+
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+	execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+	execbuf.num_cliprects = 0;
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+	fence.flags = I915_EXEC_FENCE_SIGNAL;
+	gem_execbuf(fd, &execbuf);
+
+	igt_assert(gem_bo_busy(fd, obj.handle));
+	igt_assert(syncobj_busy(fd, fence.handle));
+
+	igt_spin_free(fd, spin);
+
+	gem_sync(fd, obj.handle);
+	igt_assert(!gem_bo_busy(fd, obj.handle));
+	igt_assert(!syncobj_busy(fd, fence.handle));
+
+	syncobj_timeline_query(fd, &fence.handle, &query_value, 1);
+	igt_assert_eq(query_value, value);
+
+	gem_close(fd, obj.handle);
+	syncobj_destroy(fd, fence.handle);
+}
+
+static const char *test_syncobj_timeline_wait_desc =
+	"Verifies that waiting on a timeline syncobj point between engines"
+	" works";
+static void test_syncobj_timeline_wait(int fd)
+{
+	const uint32_t bbe[2] = {
+		MI_BATCH_BUFFER_END,
+		MI_NOOP,
+	};
+	uint32_t gem_context = gem_context_create(fd);
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+	struct drm_i915_gem_exec_fence fence = {
+		.handle = syncobj_create(fd, 0),
+	};
+	uint64_t value = 1;
+	igt_spin_t *spin;
+	unsigned handle[16];
+	int n;
+
+	/* Check that we can use the syncobj to asynchronous wait prior to
+	 * execution.
+	 */
+
+	gem_quiescent_gpu(fd);
+
+	spin = igt_spin_new(fd);
+
+	gem_context_set_all_engines(fd, gem_context);
+
+
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.batch_len = sizeof(bbe);
+	execbuf.rsvd1 = gem_context;
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+	/* Queue a signaler from the blocked engine */
+	execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+	execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+	execbuf.num_cliprects = 0;
+	fence.flags = I915_EXEC_FENCE_SIGNAL;
+	gem_execbuf(fd, &execbuf);
+	igt_assert(gem_bo_busy(fd, spin->handle));
+
+	gem_close(fd, obj.handle);
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+	n = 0;
+	for_each_engine(engine, fd) {
+		obj.handle = gem_create(fd, 4096);
+		gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+		/* No inter-engine synchronisation, will complete */
+		if (engine->flags == I915_EXEC_BLT) {
+			execbuf.flags = engine->flags;
+			execbuf.cliprects_ptr = 0;
+			execbuf.num_cliprects = 0;
+			gem_execbuf(fd, &execbuf);
+			gem_sync(fd, obj.handle);
+			igt_assert(gem_bo_busy(fd, spin->handle));
+		}
+		igt_assert(gem_bo_busy(fd, spin->handle));
+
+		/* Now wait upon the blocked engine */
+		execbuf.flags = I915_EXEC_USE_EXTENSIONS | engine->flags;
+		execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+		execbuf.num_cliprects = 0;
+		fence.flags = I915_EXEC_FENCE_WAIT;
+		gem_execbuf(fd, &execbuf);
+
+		igt_assert(gem_bo_busy(fd, obj.handle));
+		handle[n++] = obj.handle;
+	}
+	syncobj_destroy(fd, fence.handle);
+
+	for (int i = 0; i < n; i++)
+		igt_assert(gem_bo_busy(fd, handle[i]));
+
+	igt_spin_free(fd, spin);
+
+	for (int i = 0; i < n; i++) {
+		gem_sync(fd, handle[i]);
+		gem_close(fd, handle[i]);
+	}
+
+	gem_context_destroy(fd, gem_context);
+}
+
+static const char *test_syncobj_timeline_export_desc =
+	"Verify exporting of timeline syncobj signaled by i915";
+static void test_syncobj_timeline_export(int fd)
+{
+	const uint32_t bbe[2] = {
+		MI_BATCH_BUFFER_END,
+		MI_NOOP,
+	};
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+	struct drm_i915_gem_exec_fence fence = {
+		.handle = syncobj_create(fd, 0),
+	};
+	uint64_t value = 1;
+	int export[2];
+	igt_spin_t *spin = igt_spin_new(fd);
+
+	/* Check that if we export the syncobj prior to use it picks up
+	 * the later fence. This allows a syncobj to establish a channel
+	 * between clients that may be updated to a later fence by either
+	 * end.
+	 */
+	for (int n = 0; n < ARRAY_SIZE(export); n++)
+		export[n] = syncobj_export(fd, fence.handle);
+
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(&fence);
+	timeline_fences.values_ptr = to_user_pointer(&value);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+	execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+	execbuf.num_cliprects = 0;
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+	fence.flags = I915_EXEC_FENCE_SIGNAL;
+	gem_execbuf(fd, &execbuf);
+
+	igt_assert(syncobj_busy(fd, fence.handle));
+	igt_assert(gem_bo_busy(fd, obj.handle));
+
+	for (int n = 0; n < ARRAY_SIZE(export); n++) {
+		uint32_t import = syncobj_import(fd, export[n]);
+		igt_assert(syncobj_busy(fd, import));
+		syncobj_destroy(fd, import);
+	}
+
+	igt_spin_free(fd, spin);
+
+	gem_sync(fd, obj.handle);
+	igt_assert(!gem_bo_busy(fd, obj.handle));
+	igt_assert(!syncobj_busy(fd, fence.handle));
+
+	gem_close(fd, obj.handle);
+	syncobj_destroy(fd, fence.handle);
+
+	for (int n = 0; n < ARRAY_SIZE(export); n++) {
+		uint32_t import = syncobj_import(fd, export[n]);
+		igt_assert(!syncobj_busy(fd, import));
+		syncobj_destroy(fd, import);
+		close(export[n]);
+	}
+}
+
+static const char *test_syncobj_timeline_repeat_desc =
+	"Verifies that waiting & signaling a same timeline syncobj point within"
+	" the same execbuf fworks";
+static void test_syncobj_timeline_repeat(int fd)
+{
+	const uint32_t bbe[2] = {
+		MI_BATCH_BUFFER_END,
+		MI_NOOP,
+	};
+	const unsigned nfences = 4096;
+	struct drm_i915_gem_exec_object2 obj;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+	struct drm_i915_gem_exec_fence *fence;
+	uint64_t *values;
+	int export;
+	igt_spin_t *spin = igt_spin_new(fd);
+
+	/* Check that we can wait on the same fence multiple times */
+	fence = calloc(nfences, sizeof(*fence));
+	values = calloc(nfences, sizeof(*values));
+	fence->handle = syncobj_create(fd, 0);
+	values[0] = 1;
+	export = syncobj_export(fd, fence->handle);
+	for (int i = 1; i < nfences; i++) {
+		fence[i].handle = syncobj_import(fd, export);
+		values[i] = i + 1;
+	}
+	close(export);
+
+	memset(&timeline_fences, 0, sizeof(timeline_fences));
+	timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+	timeline_fences.fence_count = 1;
+	timeline_fences.handles_ptr = to_user_pointer(fence);
+	timeline_fences.values_ptr = to_user_pointer(values);
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(&obj);
+	execbuf.buffer_count = 1;
+	execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+	execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+	execbuf.num_cliprects = 0;
+
+	memset(&obj, 0, sizeof(obj));
+	obj.handle = gem_create(fd, 4096);
+	gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+	for (int i = 0; i < nfences; i++)
+		fence[i].flags = I915_EXEC_FENCE_SIGNAL;
+
+	gem_execbuf(fd, &execbuf);
+
+	for (int i = 0; i < nfences; i++) {
+		igt_assert(syncobj_busy(fd, fence[i].handle));
+		/*
+		 * Timeline syncobj cannot resignal the same point
+		 * again.
+		 */
+		fence[i].flags |= I915_EXEC_FENCE_WAIT;
+	}
+	igt_assert(gem_bo_busy(fd, obj.handle));
+
+	igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+	for (int i = 0; i < nfences; i++) {
+		igt_assert(syncobj_busy(fd, fence[i].handle));
+		fence[i].flags = I915_EXEC_FENCE_WAIT;
+	}
+	igt_assert(gem_bo_busy(fd, obj.handle));
+
+	gem_execbuf(fd, &execbuf);
+
+	for (int i = 0; i < nfences; i++)
+		igt_assert(syncobj_busy(fd, fence[i].handle));
+	igt_assert(gem_bo_busy(fd, obj.handle));
+
+	igt_spin_free(fd, spin);
+
+	gem_sync(fd, obj.handle);
+	gem_close(fd, obj.handle);
+
+	for (int i = 0; i < nfences; i++) {
+		igt_assert(!syncobj_busy(fd, fence[i].handle));
+		syncobj_destroy(fd, fence[i].handle);
+	}
+	free(fence);
+	free(values);
+}
+
 igt_main
 {
 	const struct intel_execution_engine *e;
@@ -1536,6 +2135,50 @@ igt_main
 		}
 	}
 
+	igt_subtest_group { /* syncobj timeline */
+		igt_fixture {
+			igt_require(exec_has_timeline_fences(i915));
+			igt_assert(has_syncobj_timeline(i915));
+			igt_fork_hang_detector(i915);
+		}
+
+		igt_describe(test_invalid_timeline_fence_array_desc);
+		igt_subtest("invalid-timeline-fence-array")
+			test_invalid_timeline_fence_array(i915);
+
+		igt_describe(test_syncobj_timeline_unused_fence_desc);
+		igt_subtest("syncobj-timeline-unused-fence")
+			test_syncobj_timeline_unused_fence(i915);
+
+		igt_describe(test_syncobj_timeline_invalid_wait_desc);
+		igt_subtest("syncobj-timeline-invalid-wait")
+			test_syncobj_timeline_invalid_wait(i915);
+
+		igt_describe(test_syncobj_timeline_invalid_flags_desc);
+		igt_subtest("syncobj-timeline-invalid-flags")
+			test_syncobj_timeline_invalid_flags(i915);
+
+		igt_describe(test_syncobj_timeline_signal_desc);
+		igt_subtest("syncobj-timeline-signal")
+			test_syncobj_timeline_signal(i915);
+
+		igt_describe(test_syncobj_timeline_wait_desc);
+		igt_subtest("syncobj-timeline-wait")
+			test_syncobj_timeline_wait(i915);
+
+		igt_describe(test_syncobj_timeline_export_desc);
+		igt_subtest("syncobj-timeline-export")
+			test_syncobj_timeline_export(i915);
+
+		igt_describe(test_syncobj_timeline_repeat_desc);
+		igt_subtest("syncobj-timeline-repeat")
+			test_syncobj_timeline_repeat(i915);
+
+		igt_fixture {
+			igt_stop_hang_detector();
+		}
+	}
+
 	igt_fixture {
 		close(i915);
 	}
-- 
2.24.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [igt-dev] [PATCH i-g-t 09/10] lib/i915: add mmio base for engines
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
                   ` (5 preceding siblings ...)
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 08/10] tests/i915/exec_fence: add timeline fence tests Lionel Landwerlin
@ 2019-11-20 21:21 ` Lionel Landwerlin
  2019-11-20 21:42   ` Chris Wilson
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 10/10] tests/i915/gem_exec_fence: add engine chaining tests Lionel Landwerlin
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-20 21:21 UTC (permalink / raw)
  To: igt-dev

Useful when you want to work with MI_ALU and general purpose registers
local to an engine.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 lib/i915/gem_engine_topology.c | 74 ++++++++++++++++++++++++++++++++++
 lib/i915/gem_engine_topology.h |  5 +++
 2 files changed, 79 insertions(+)

diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
index 790d455f..925fdb51 100644
--- a/lib/i915/gem_engine_topology.c
+++ b/lib/i915/gem_engine_topology.c
@@ -22,6 +22,7 @@
  */
 
 #include "drmtest.h"
+#include "intel_chipset.h"
 #include "ioctl_wrappers.h"
 
 #include "i915/gem_engine_topology.h"
@@ -337,3 +338,76 @@ bool gem_engine_is_equal(const struct intel_execution_engine2 *e1,
 {
 	return e1->class == e2->class && e1->instance == e2->instance;
 }
+
+uint32_t intel_get_engine_mmio_base(const uint16_t devid,
+				    const struct intel_execution_engine2 *e)
+{
+	switch (e->class) {
+	case I915_ENGINE_CLASS_RENDER:
+		return 0x2000;
+	case I915_ENGINE_CLASS_COPY:
+		return 0x22000;
+	case I915_ENGINE_CLASS_VIDEO: {
+		uint32_t gen11_bases[] = {
+			0x1c0000,
+			0x1c4000,
+			0x1d0000,
+			0x1d4000,
+		};
+		uint32_t gen8_bases[] = {
+			0x12000,
+			0x1c000,
+		};
+		uint32_t gen6_bases[] = {
+			0x12000,
+		};
+		uint32_t gen4_bases[] = {
+			0x4000,
+		};
+		uint32_t *bases, len = 0;
+
+		if (AT_LEAST_GEN(devid, 11)) {
+			bases = gen11_bases;
+			len = ARRAY_SIZE(gen11_bases);
+		} else if (AT_LEAST_GEN(devid, 8)) {
+			bases = gen8_bases;
+			len = ARRAY_SIZE(gen8_bases);
+		} else if (AT_LEAST_GEN(devid, 6)) {
+			bases = gen6_bases;
+			len = ARRAY_SIZE(gen6_bases);
+		} else if (AT_LEAST_GEN(devid, 4)) {
+			bases = gen4_bases;
+			len = ARRAY_SIZE(gen4_bases);
+		}
+
+		if (e->instance >= len)
+			igt_assert(!"Invalid vcs instance");
+		return bases[e->instance];
+	}
+	case I915_ENGINE_CLASS_VIDEO_ENHANCE: {
+		uint32_t gen11_bases[] = {
+			0x1c8000,
+			0x1d8000,
+		};
+		uint32_t gen7_bases[] = {
+			0x1a000,
+		};
+		uint32_t *bases, len = 0;
+
+		if (AT_LEAST_GEN(devid, 11)) {
+			bases = gen11_bases;
+			len = ARRAY_SIZE(gen11_bases);
+		} else if (AT_LEAST_GEN(devid, 7)) {
+			bases = gen7_bases;
+			len = ARRAY_SIZE(gen7_bases);
+		}
+
+		if (e->instance >= len)
+			igt_assert(!"Invalid vcs instance");
+		return bases[e->instance];
+	}
+
+	default:
+		igt_assert(!"Invalid engine class");
+	}
+}
diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
index d98773e0..71ce81de 100644
--- a/lib/i915/gem_engine_topology.h
+++ b/lib/i915/gem_engine_topology.h
@@ -27,6 +27,8 @@
 #include "igt_gt.h"
 #include "i915_drm.h"
 
+struct intel_device_info;
+
 #define GEM_MAX_ENGINES		I915_EXEC_RING_MASK + 1
 
 struct intel_engine_data {
@@ -46,6 +48,9 @@ intel_get_current_engine(struct intel_engine_data *ed);
 struct intel_execution_engine2 *
 intel_get_current_physical_engine(struct intel_engine_data *ed);
 
+uint32_t intel_get_engine_mmio_base(const uint16_t devid,
+				    const struct intel_execution_engine2 *e);
+
 void intel_next_engine(struct intel_engine_data *ed);
 
 int gem_context_lookup_engine(int fd, uint64_t engine, uint32_t ctx_id,
-- 
2.24.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [igt-dev] [PATCH i-g-t 10/10] tests/i915/gem_exec_fence: add engine chaining tests
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
                   ` (6 preceding siblings ...)
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 09/10] lib/i915: add mmio base for engines Lionel Landwerlin
@ 2019-11-20 21:21 ` Lionel Landwerlin
  2019-11-20 22:02   ` Chris Wilson
       [not found] ` <20191120212143.364333-5-lionel.g.landwerlin@intel.com>
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-20 21:21 UTC (permalink / raw)
  To: igt-dev

Those tests are meant to verify the ordering while messing around with
the timeline points.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 lib/intel_reg.h             |   2 +
 tests/i915/gem_exec_fence.c | 634 ++++++++++++++++++++++++++++++++++++
 2 files changed, 636 insertions(+)

diff --git a/lib/intel_reg.h b/lib/intel_reg.h
index 96236828..f01933c1 100644
--- a/lib/intel_reg.h
+++ b/lib/intel_reg.h
@@ -2594,6 +2594,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 /* Batch */
 #define MI_BATCH_BUFFER		((0x30 << 23) | 1)
 #define MI_BATCH_BUFFER_START	(0x31 << 23)
+#define MI_BATCH_BUFFER_START_GEN8 ((0x31 << 13) | 1)
+#define   MI_BATCH_PREDICATE       (1 << 15) /* HSW+ on RCS only*/
 #define MI_BATCH_BUFFER_END	(0xA << 23)
 #define MI_COND_BATCH_BUFFER_END	(0x36 << 23)
 #define MI_DO_COMPARE                   (1 << 21)
diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index b38d19bf..a3d5d0b6 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -1961,6 +1961,616 @@ static void test_syncobj_timeline_repeat(int fd)
 	free(values);
 }
 
+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+
+/* #define MI_LOAD_REGISTER_MEM	   (MI_INSTR(0x29, 1) */
+/* #define MI_LOAD_REGISTER_MEM_GEN8  MI_INSTR(0x29, 2) */
+
+#define MI_LOAD_REGISTER_REG       MI_INSTR(0x2A, 1)
+
+#define MI_STORE_REGISTER_MEM      MI_INSTR(0x24, 1)
+#define MI_STORE_REGISTER_MEM_GEN8 MI_INSTR(0x24, 2)
+
+#define MI_MATH(x)                 MI_INSTR(0x1a, (x) - 1)
+#define MI_MATH_INSTR(opcode, op1, op2) ((opcode) << 20 | (op1) << 10 | (op2))
+/* Opcodes for MI_MATH_INSTR */
+#define   MI_MATH_NOOP			MI_MATH_INSTR(0x00,  0x0, 0x0)
+#define   MI_MATH_LOAD(op1, op2)	MI_MATH_INSTR(0x80,  op1, op2)
+#define   MI_MATH_LOADINV(op1, op2)	MI_MATH_INSTR(0x480, op1, op2)
+#define   MI_MATH_ADD			MI_MATH_INSTR(0x100, 0x0, 0x0)
+#define   MI_MATH_SUB			MI_MATH_INSTR(0x101, 0x0, 0x0)
+#define   MI_MATH_AND			MI_MATH_INSTR(0x102, 0x0, 0x0)
+#define   MI_MATH_OR			MI_MATH_INSTR(0x103, 0x0, 0x0)
+#define   MI_MATH_XOR			MI_MATH_INSTR(0x104, 0x0, 0x0)
+#define   MI_MATH_STORE(op1, op2)	MI_MATH_INSTR(0x180, op1, op2)
+#define   MI_MATH_STOREINV(op1, op2)	MI_MATH_INSTR(0x580, op1, op2)
+/* Registers used as operands in MI_MATH_INSTR */
+#define   MI_MATH_REG(x)		(x)
+#define   MI_MATH_REG_SRCA		0x20
+#define   MI_MATH_REG_SRCB		0x21
+#define   MI_MATH_REG_ACCU		0x31
+#define   MI_MATH_REG_ZF		0x32
+#define   MI_MATH_REG_CF		0x33
+
+#define HSW_CS_GPR(n)                   (0x600 + 8*(n))
+#define RING_TIMESTAMP                  (0x358)
+#define MI_PREDICATE_RESULT_1           (0x41c)
+
+struct inter_engine_context {
+	int fd;
+
+	struct {
+		uint32_t context;
+	} iterations[9];
+
+	struct intel_engine_data *engines;
+
+	struct inter_engine_batches {
+		void *increment_bb;
+		uint32_t increment_bb_len;
+		uint32_t increment_bb_handle;
+
+		uint32_t timeline;
+
+		void *read0_ptrs[2];
+		void *read1_ptrs[2];
+		void *write_ptrs[2];
+	} *batches;
+
+	void *wait_bb;
+	uint32_t wait_bb_len;
+	uint32_t wait_bb_handle;
+
+	void *jump_ptr;
+	void *timestamp2_ptr;
+
+	uint32_t wait_context;
+	uint32_t wait_timeline;
+
+	struct drm_i915_gem_exec_object2 engine_counter_object;
+};
+
+static void submit_timeline_execbuf(struct inter_engine_context *context,
+				    struct drm_i915_gem_execbuffer2 *execbuf,
+				    uint32_t run_engine_idx,
+				    uint32_t wait_syncobj,
+				    uint64_t wait_value,
+				    uint32_t signal_syncobj,
+				    uint64_t signal_value)
+{
+	uint64_t values[2] = { 0, };
+	struct drm_i915_gem_exec_fence fences[2] = { 0, };
+	struct drm_i915_gem_execbuffer_ext_timeline_fences fence_list = {
+		.base = {
+			.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES,
+		},
+		.handles_ptr = to_user_pointer(fences),
+		.values_ptr = to_user_pointer(values),
+	};
+
+	if (wait_syncobj) {
+		fences[fence_list.fence_count] = (struct drm_i915_gem_exec_fence) {
+			.handle = wait_syncobj,
+			.flags = I915_EXEC_FENCE_WAIT,
+		};
+		values[fence_list.fence_count] = wait_value;
+		fence_list.fence_count++;
+	}
+
+	if (signal_syncobj) {
+		fences[fence_list.fence_count] = (struct drm_i915_gem_exec_fence) {
+			.handle = signal_syncobj,
+			.flags = I915_EXEC_FENCE_SIGNAL,
+		};
+		values[fence_list.fence_count] = signal_value;
+		fence_list.fence_count++;
+	}
+
+	if (wait_syncobj || signal_syncobj) {
+		execbuf->flags |= I915_EXEC_USE_EXTENSIONS;
+		execbuf->cliprects_ptr = to_user_pointer(&fence_list);
+	}
+
+	execbuf->flags |= context->engines->engines[run_engine_idx].flags;
+
+	gem_execbuf(context->fd, execbuf);
+}
+
+static void build_wait_bb(struct inter_engine_context *context,
+			  uint64_t delay,
+			  uint64_t timestamp_frequency)
+{
+	uint32_t *bb = context->wait_bb = calloc(1, 4096);
+	uint64_t wait_value =
+		0xffffffffffffffff - (delay * timestamp_frequency) / NSEC_PER_SEC;
+
+	igt_debug("wait_value=0x%lx\n", wait_value);
+
+	*bb++ = MI_LOAD_REGISTER_IMM;
+	*bb++ = 0x2000 + HSW_CS_GPR(0);
+	*bb++ = wait_value & 0xffffffff;
+	*bb++ = MI_LOAD_REGISTER_IMM;
+	*bb++ = 0x2000 + HSW_CS_GPR(0) + 4;
+	*bb++ = wait_value >> 32;
+
+	*bb++ = MI_LOAD_REGISTER_REG;
+	*bb++ = 0x2000 + RING_TIMESTAMP;
+	*bb++ = 0x2000 + HSW_CS_GPR(1);
+	*bb++ = MI_LOAD_REGISTER_IMM;
+	*bb++ = 0x2000 + HSW_CS_GPR(1) + 4;
+	*bb++ = 0;
+
+	context->timestamp2_ptr = bb;
+	*bb++ = MI_LOAD_REGISTER_REG;
+	*bb++ = 0x2000 + RING_TIMESTAMP;
+	*bb++ = 0x2000 + HSW_CS_GPR(2);
+	*bb++ = MI_LOAD_REGISTER_IMM;
+	*bb++ = 0x2000 + HSW_CS_GPR(2) + 4;
+	*bb++ = 0;
+
+	*bb++ = MI_MATH(4);
+	*bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCA, MI_MATH_REG(2));
+	*bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCB, MI_MATH_REG(1));
+	*bb++ = MI_MATH_SUB;
+	*bb++ = MI_MATH_STORE(MI_MATH_REG(3), MI_MATH_REG_ACCU);
+
+	*bb++ = MI_MATH(4);
+	*bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCA, MI_MATH_REG(0));
+	*bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCB, MI_MATH_REG(3));
+	*bb++ = MI_MATH_ADD;
+	*bb++ = MI_MATH_STOREINV(MI_MATH_REG(4), MI_MATH_REG_CF);
+
+	*bb++ = MI_LOAD_REGISTER_REG;
+	*bb++ = 0x2000 + HSW_CS_GPR(4);
+	*bb++ = 0x2000 + MI_PREDICATE_RESULT_1;
+
+	*bb++ = MI_BATCH_BUFFER_START | MI_BATCH_PREDICATE | 1;
+	context->jump_ptr = bb;
+	*bb++ = 0;
+	*bb++ = 0;
+
+	*bb++ = MI_BATCH_BUFFER_END;
+
+	context->wait_bb_len = ALIGN((void *) bb - context->wait_bb, 8);
+}
+
+static void wait_engine(struct inter_engine_context *context,
+			uint32_t run_engine_idx,
+			uint32_t signal_syncobj,
+			uint64_t signal_value)
+{
+	struct drm_i915_gem_relocation_entry relocs[1];
+	struct drm_i915_gem_exec_object2 objects[2] = {
+		context->engine_counter_object,
+		{
+			.handle = context->wait_bb_handle,
+			.relocs_ptr = to_user_pointer(&relocs),
+			.relocation_count = ARRAY_SIZE(relocs),
+		},
+	};
+	struct drm_i915_gem_execbuffer2 execbuf = {
+		.buffers_ptr = to_user_pointer(&objects[0]),
+		.buffer_count = 2,
+		.flags = I915_EXEC_HANDLE_LUT,
+		.rsvd1 = context->wait_context,
+		.batch_len = context->wait_bb_len,
+	};
+
+	memset(&relocs, 0, sizeof(relocs));
+
+	/* MI_BATCH_BUFFER_START */
+	relocs[0].target_handle = 1;
+	relocs[0].delta = context->timestamp2_ptr - context->wait_bb;
+	relocs[0].offset = context->jump_ptr - context->wait_bb;
+	relocs[0].presumed_offset = -1;
+
+	submit_timeline_execbuf(context, &execbuf, run_engine_idx,
+				0, 0,
+				signal_syncobj, signal_value);
+}
+
+static void build_increment_engine_bb(struct inter_engine_batches *batch,
+				      uint32_t mmio_base)
+{
+	uint32_t *bb = batch->increment_bb = calloc(1, 4096);
+
+	*bb++ = MI_LOAD_REGISTER_MEM_GEN8;
+	*bb++ = mmio_base + HSW_CS_GPR(0);
+	batch->read0_ptrs[0] = bb;
+	*bb++ = 0;
+	*bb++ = 0;
+	*bb++ = MI_LOAD_REGISTER_MEM_GEN8;
+	*bb++ = mmio_base + HSW_CS_GPR(0) + 4;
+	batch->read0_ptrs[1] = bb;
+	*bb++ = 0;
+	*bb++ = 0;
+
+	*bb++ = MI_LOAD_REGISTER_MEM_GEN8;
+	*bb++ = mmio_base + HSW_CS_GPR(1);
+	batch->read1_ptrs[0] = bb;
+	*bb++ = 0;
+	*bb++ = 0;
+	*bb++ = MI_LOAD_REGISTER_MEM_GEN8;
+	*bb++ = mmio_base + HSW_CS_GPR(1) + 4;
+	batch->read1_ptrs[1] = bb;
+	*bb++ = 0;
+	*bb++ = 0;
+
+	*bb++ = MI_MATH(4);
+	*bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCA, MI_MATH_REG(0));
+	*bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCB, MI_MATH_REG(1));
+	*bb++ = MI_MATH_ADD;
+	*bb++ = MI_MATH_STORE(MI_MATH_REG(0), MI_MATH_REG_ACCU);
+
+	*bb++ = MI_STORE_REGISTER_MEM_GEN8;
+	*bb++ = mmio_base + HSW_CS_GPR(0);
+	batch->write_ptrs[0] = bb;
+	*bb++ = 0;
+	*bb++ = 0;
+	*bb++ = MI_STORE_REGISTER_MEM_GEN8;
+	*bb++ = mmio_base + HSW_CS_GPR(0) + 4;
+	batch->write_ptrs[1] = bb;
+	*bb++ = 0;
+	*bb++ = 0;
+
+	*bb++ = MI_BATCH_BUFFER_END;
+
+	batch->increment_bb_len = ALIGN((void *) bb - batch->increment_bb, 8);
+}
+
+static void increment_engine(struct inter_engine_context *context,
+			     uint32_t gem_context,
+			     uint32_t read0_engine_idx,
+			     uint32_t read1_engine_idx,
+			     uint32_t write_engine_idx,
+			     uint32_t wait_syncobj,
+			     uint64_t wait_value,
+			     uint32_t signal_syncobj,
+			     uint64_t signal_value)
+{
+	struct inter_engine_batches *batch = &context->batches[write_engine_idx];
+	struct drm_i915_gem_relocation_entry relocs[3 * 2];
+	struct drm_i915_gem_exec_object2 objects[2] = {
+		context->engine_counter_object,
+		{
+			.handle = batch->increment_bb_handle,
+			.relocs_ptr = to_user_pointer(relocs),
+			.relocation_count = ARRAY_SIZE(relocs),
+		},
+	};
+	struct drm_i915_gem_execbuffer2 execbuf = {
+		.buffers_ptr = to_user_pointer(&objects[0]),
+		.buffer_count = ARRAY_SIZE(objects),
+		.flags = I915_EXEC_HANDLE_LUT,
+		.rsvd1 = gem_context,
+		.batch_len = batch->increment_bb_len,
+	};
+
+	memset(relocs, 0, sizeof(relocs));
+
+	/* MI_LOAD_REGISTER_MEM */
+	relocs[0].target_handle = 0;
+	relocs[0].delta = read0_engine_idx * 8;
+	relocs[0].offset = batch->read0_ptrs[0] - batch->increment_bb;
+	relocs[0].presumed_offset = -1;
+	relocs[1].target_handle = 0;
+	relocs[1].delta = read0_engine_idx * 8 + 4;
+	relocs[1].offset = batch->read0_ptrs[1] - batch->increment_bb;
+	relocs[1].presumed_offset = -1;
+
+	/* MI_LOAD_REGISTER_MEM */
+	relocs[2].target_handle = 0;
+	relocs[2].delta = read1_engine_idx * 8;
+	relocs[2].offset = batch->read1_ptrs[0] - batch->increment_bb;
+	relocs[2].presumed_offset = -1;
+	relocs[3].target_handle = 0;
+	relocs[3].delta = read1_engine_idx * 8 + 4;
+	relocs[3].offset = batch->read1_ptrs[1] - batch->increment_bb;
+	relocs[3].presumed_offset = -1;
+
+	/* MI_STORE_REGISTER_MEM */
+	relocs[4].target_handle = 0;
+	relocs[4].delta = write_engine_idx * 8;
+	relocs[4].offset = batch->write_ptrs[0] - batch->increment_bb;
+	relocs[4].presumed_offset = -1;
+	relocs[5].target_handle = 0;
+	relocs[5].delta = write_engine_idx * 8 + 4;
+	relocs[5].offset = batch->write_ptrs[1] - batch->increment_bb;
+	relocs[5].presumed_offset = -1;
+
+	submit_timeline_execbuf(context, &execbuf, write_engine_idx,
+				wait_syncobj, wait_value,
+				signal_syncobj, signal_value);
+
+	context->engine_counter_object = objects[0];
+}
+
+static uint64_t fib(uint32_t iters)
+{
+	uint64_t last_value = 0;
+	uint64_t value = 1;
+	uint32_t i = 0;
+
+	while (i < iters) {
+		uint64_t new_value = value + last_value;
+
+		last_value = value;
+		value = new_value;
+		i++;
+	}
+
+	return last_value;
+}
+
+static uint64_t
+get_cs_timestamp_frequency(int fd)
+{
+	int cs_ts_freq = 0;
+	drm_i915_getparam_t gp;
+
+	gp.param = I915_PARAM_CS_TIMESTAMP_FREQUENCY;
+	gp.value = &cs_ts_freq;
+	if (igt_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0)
+		return cs_ts_freq;
+
+	igt_skip("Kernel with PARAM_CS_TIMESTAMP_FREQUENCY support required\n");
+}
+
+static void setup_timeline_chain_engines(struct inter_engine_context *context, int fd, struct intel_engine_data *engines)
+{
+	const uint16_t devid = intel_get_drm_devid(fd);
+
+	memset(context, 0, sizeof(*context));
+
+	context->fd = fd;
+	context->engines = engines;
+
+	context->wait_context = gem_context_create(fd);
+	context->wait_timeline = syncobj_create(fd, 0);
+
+	context->engine_counter_object.handle = gem_create(fd, 4096);
+
+	for (uint32_t i = 0; i < ARRAY_SIZE(context->iterations); i++) {
+		context->iterations[i].context = gem_context_create(fd);
+
+		gem_context_set_all_engines(fd, context->iterations[i].context);
+
+		/* Give a different priority to all contexts. */
+		gem_context_set_priority(fd, context->iterations[i].context,
+					 I915_CONTEXT_MAX_USER_PRIORITY - ARRAY_SIZE(context->iterations) + i);
+	}
+
+	build_wait_bb(context, 20 * 1000 * 1000ull /* 20ms */, get_cs_timestamp_frequency(fd));
+	context->wait_bb_handle = gem_create(fd, 4096);
+	gem_write(fd, context->wait_bb_handle, 0,
+		  context->wait_bb, context->wait_bb_len);
+
+	context->batches = calloc(engines->nengines, sizeof(*context->batches));
+	for (uint32_t e = 0; e < engines->nengines; e++) {
+		struct inter_engine_batches *batches = &context->batches[e];
+
+		batches->timeline = syncobj_create(fd, 0);
+
+		build_increment_engine_bb(
+			batches,
+			intel_get_engine_mmio_base(devid,
+						   &engines->engines[e]));
+		batches->increment_bb_handle = gem_create(fd, 4096);
+		gem_write(fd, batches->increment_bb_handle, 0,
+			  batches->increment_bb, batches->increment_bb_len);
+	}
+
+	for (uint32_t i = 0; i < 10; i++)
+		igt_debug("%u = %lu\n", i, fib(i));
+
+	/* Bootstrap the fibonacci sequence */
+	{
+		uint64_t dword = 1;
+		gem_write(fd, context->engine_counter_object.handle,
+			  sizeof(dword) * (context->engines->nengines - 1),
+			  &dword, sizeof(dword));
+	}
+}
+
+static void teardown_timeline_chain_engines(struct inter_engine_context *context)
+{
+	gem_close(context->fd, context->engine_counter_object.handle);
+
+	for (uint32_t i = 0; i < ARRAY_SIZE(context->iterations); i++) {
+		gem_context_destroy(context->fd, context->iterations[i].context);
+	}
+
+	gem_context_destroy(context->fd, context->wait_context);
+	syncobj_destroy(context->fd, context->wait_timeline);
+	gem_close(context->fd, context->wait_bb_handle);
+	free(context->wait_bb);
+
+	for (uint32_t e = 0; e < context->engines->nengines; e++) {
+		struct inter_engine_batches *batches = &context->batches[e];
+
+		syncobj_destroy(context->fd, batches->timeline);
+		gem_close(context->fd, batches->increment_bb_handle);
+		free(batches->increment_bb);
+	}
+	free(context->batches);
+}
+
+static void test_syncobj_timeline_chain_engines(int fd, struct intel_engine_data *engines)
+{
+	struct inter_engine_context ctx;
+	uint64_t *counter_output;
+
+	setup_timeline_chain_engines(&ctx, fd, engines);
+
+	/*
+	 * Delay all the other operations by making them depend on an
+	 * active wait on the RCS.
+	 */
+	wait_engine(&ctx, 0, ctx.wait_timeline, 1);
+
+	for (uint32_t iter = 0; iter < ARRAY_SIZE(ctx.iterations); iter++) {
+		for (uint32_t engine = 0; engine < engines->nengines; engine++) {
+			uint32_t prev_prev_engine =
+				(engines->nengines + engine - 2) % engines->nengines;
+			uint32_t prev_engine =
+				(engines->nengines + engine - 1) % engines->nengines;
+			/*
+			 * Pick up the wait engine semaphore for the
+			 * first increment, then pick up the previous
+			 * engine's timeline.
+			 */
+			uint32_t wait_syncobj =
+				iter == 0 && engine == 0 ?
+				ctx.wait_timeline : ctx.batches[prev_engine].timeline;
+			uint32_t wait_value =
+				iter == 0 && engine == 0 ?
+				1 : (engine == 0 ? iter : (iter + 1));
+
+			increment_engine(&ctx, ctx.iterations[iter].context,
+					 prev_prev_engine /* read0 engine */,
+					 prev_engine /* read1 engine */,
+					 engine /* write engine */,
+					 wait_syncobj, wait_value,
+					 ctx.batches[engine].timeline, iter + 1);
+		}
+	}
+
+	gem_sync(fd, ctx.engine_counter_object.handle);
+
+	counter_output = gem_mmap__wc(fd, ctx.engine_counter_object.handle, 0, 4096, PROT_READ);
+
+	for (uint32_t i = 0; i < ctx.engines->nengines; i++)
+		igt_debug("engine %i (%s)\t= %016lx\n", i,
+			  ctx.engines->engines[i].name, counter_output[i]);
+
+	/*
+	 * Verify that we get the fibonacci number expected (we start
+	 * at the sequence on the second number : 1).
+	 */
+	igt_assert_eq(counter_output[engines->nengines - 1],
+		      fib(ARRAY_SIZE(ctx.iterations) * engines->nengines + 1));
+
+	teardown_timeline_chain_engines(&ctx);
+}
+
+static void test_syncobj_stationary_timeline_chain_engines(int fd, struct intel_engine_data *engines)
+{
+	struct inter_engine_context ctx;
+	uint64_t *counter_output;
+
+	setup_timeline_chain_engines(&ctx, fd, engines);
+
+	/*
+	 * Delay all the other operations by making them depend on an
+	 * active wait on the RCS.
+	 */
+	wait_engine(&ctx, 0, ctx.wait_timeline, 1);
+
+	for (uint32_t iter = 0; iter < ARRAY_SIZE(ctx.iterations); iter++) {
+		for (uint32_t engine = 0; engine < engines->nengines; engine++) {
+			uint32_t prev_prev_engine =
+				(engines->nengines + engine - 2) % engines->nengines;
+			uint32_t prev_engine =
+				(engines->nengines + engine - 1) % engines->nengines;
+			/*
+			 * Pick up the wait engine semaphore for the
+			 * first increment, then pick up the previous
+			 * engine's timeline.
+			 */
+			uint32_t wait_syncobj =
+				iter == 0 && engine == 0 ?
+				ctx.wait_timeline : ctx.batches[prev_engine].timeline;
+			/*
+			 * Always signal the value 10. Because the
+			 * signal operations are submitted in order,
+			 * we should always pickup the right
+			 * dma-fence.
+			 */
+			uint32_t wait_value =
+				iter == 0 && engine == 0 ?
+				1 : 10;
+
+			increment_engine(&ctx, ctx.iterations[iter].context,
+					 prev_prev_engine /* read0 engine */,
+					 prev_engine /* read1 engine */,
+					 engine /* write engine */,
+					 wait_syncobj, wait_value,
+					 ctx.batches[engine].timeline, 10);
+		}
+	}
+
+	gem_sync(fd, ctx.engine_counter_object.handle);
+
+	counter_output = gem_mmap__wc(fd, ctx.engine_counter_object.handle, 0, 4096, PROT_READ);
+
+	for (uint32_t i = 0; i < ctx.engines->nengines; i++)
+		igt_debug("engine %i (%s)\t= %016lx\n", i,
+			  ctx.engines->engines[i].name, counter_output[i]);
+	igt_assert_eq(counter_output[engines->nengines - 1],
+		      fib(ARRAY_SIZE(ctx.iterations) * engines->nengines + 1));
+
+	teardown_timeline_chain_engines(&ctx);
+}
+
+static void test_syncobj_backward_timeline_chain_engines(int fd, struct intel_engine_data *engines)
+{
+	struct inter_engine_context ctx;
+	uint64_t *counter_output;
+
+	setup_timeline_chain_engines(&ctx, fd, engines);
+
+	/*
+	 * Delay all the other operations by making them depend on an
+	 * active wait on the RCS.
+	 */
+	wait_engine(&ctx, 0, ctx.wait_timeline, 1);
+
+	for (uint32_t iter = 0; iter < ARRAY_SIZE(ctx.iterations); iter++) {
+		for (uint32_t engine = 0; engine < engines->nengines; engine++) {
+			uint32_t prev_prev_engine =
+				(engines->nengines + engine - 2) % engines->nengines;
+			uint32_t prev_engine =
+				(engines->nengines + engine - 1) % engines->nengines;
+			/*
+			 * Pick up the wait engine semaphore for the
+			 * first increment, then pick up the previous
+			 * engine's timeline.
+			 */
+			uint32_t wait_syncobj =
+				iter == 0 && engine == 0 ?
+				ctx.wait_timeline : ctx.batches[prev_engine].timeline;
+			/*
+			 * Always signal the value 10. Because the
+			 * signal operations are submitted in order,
+			 * we should always pickup the right
+			 * dma-fence.
+			 */
+			uint32_t wait_value =
+				iter == 0 && engine == 0 ?
+				1 : 1;
+
+			increment_engine(&ctx, ctx.iterations[iter].context,
+					 prev_prev_engine /* read0 engine */,
+					 prev_engine /* read1 engine */,
+					 engine /* write engine */,
+					 wait_syncobj, wait_value,
+					 ctx.batches[engine].timeline, ARRAY_SIZE(ctx.iterations) - iter);
+		}
+	}
+
+	gem_sync(fd, ctx.engine_counter_object.handle);
+
+	counter_output = gem_mmap__wc(fd, ctx.engine_counter_object.handle, 0, 4096, PROT_READ);
+
+	for (uint32_t i = 0; i < ctx.engines->nengines; i++)
+		igt_debug("engine %i (%s)\t= %016lx\n", i,
+			  ctx.engines->engines[i].name, counter_output[i]);
+	igt_assert_eq(counter_output[engines->nengines - 1],
+		      fib(ARRAY_SIZE(ctx.iterations) * engines->nengines + 1));
+
+	teardown_timeline_chain_engines(&ctx);
+}
+
 igt_main
 {
 	const struct intel_execution_engine *e;
@@ -2174,6 +2784,30 @@ igt_main
 		igt_subtest("syncobj-timeline-repeat")
 			test_syncobj_timeline_repeat(i915);
 
+		igt_subtest_group { /* syncobj timeline engine chaining */
+			struct intel_engine_data engines;
+
+			igt_fixture {
+				/*
+				 * We need support for MI_ALU on all
+				 * engines which seems to be there
+				 * only on Gen8+
+				 */
+				igt_require(intel_gen(intel_get_drm_devid(i915)) >= 8);
+				igt_require(engines.nengines > 1);
+				engines = intel_init_engine_list(i915, 0);
+			}
+
+			igt_subtest("syncobj-timeline-chain-engines")
+				test_syncobj_timeline_chain_engines(i915, &engines);
+
+			igt_subtest("syncobj-stationary-timeline-chain-engines")
+				test_syncobj_stationary_timeline_chain_engines(i915, &engines);
+
+			igt_subtest("syncobj-backward-timeline-chain-engines")
+				test_syncobj_backward_timeline_chain_engines(i915, &engines);
+		}
+
 		igt_fixture {
 			igt_stop_hang_detector();
 		}
-- 
2.24.0

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 04/10] tests/syncobj_timeline: add more timeline tests
       [not found] ` <20191120212143.364333-5-lionel.g.landwerlin@intel.com>
@ 2019-11-20 21:33   ` Chris Wilson
  0 siblings, 0 replies; 24+ messages in thread
From: Chris Wilson @ 2019-11-20 21:33 UTC (permalink / raw)
  To: Lionel Landwerlin, igt-dev

Quoting Lionel Landwerlin (2019-11-20 21:21:37)
> +struct checker_thread_data {
> +       int fd;
> +       uint32_t syncobj;
> +       bool running;
> +       bool started;
> +};
> +
> +static void *
> +checker_thread_func(void *_data)
> +{
> +       struct checker_thread_data *data = _data;
> +       uint64_t value, last_value = 0;
> +
> +       while (data->running) {

while (READ_ONCE(data->running)) {

to make sure gcc does not get too clever (surprisingly it does happen,
but I expect syncobj_timeline_query() to be a treated as a barrier as it
will have a syscall).

> +               syncobj_timeline_query(data->fd, &data->syncobj, &value, 1);
> +
> +               data->started = true;
> +
> +               igt_assert(last_value <= value);
> +               last_value = value;
> +       }
> +
> +       return NULL;
> +}
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 08/10] tests/i915/exec_fence: add timeline fence tests
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 08/10] tests/i915/exec_fence: add timeline fence tests Lionel Landwerlin
@ 2019-11-20 21:40   ` Chris Wilson
  0 siblings, 0 replies; 24+ messages in thread
From: Chris Wilson @ 2019-11-20 21:40 UTC (permalink / raw)
  To: Lionel Landwerlin, igt-dev

Quoting Lionel Landwerlin (2019-11-20 21:21:41)
> +static void test_syncobj_timeline_signal(int fd)
> +{
> +       const uint32_t bbe = MI_BATCH_BUFFER_END;
> +       struct drm_i915_gem_exec_object2 obj;
> +       struct drm_i915_gem_execbuffer2 execbuf;
> +       struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
> +       struct drm_i915_gem_exec_fence fence = {
> +               .handle = syncobj_create(fd, 0),
> +       };
> +       uint64_t value = 42, query_value;
> +       igt_spin_t *spin = igt_spin_new(fd);
> +
> +       /* Check that the syncobj is signaled only when our request/fence is */
> +
> +       memset(&timeline_fences, 0, sizeof(timeline_fences));
> +       timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
> +       timeline_fences.fence_count = 1;
> +       timeline_fences.handles_ptr = to_user_pointer(&fence);
> +       timeline_fences.values_ptr = to_user_pointer(&value);
> +
> +       memset(&execbuf, 0, sizeof(execbuf));
> +       execbuf.buffers_ptr = to_user_pointer(&obj);
> +       execbuf.buffer_count = 1;
> +       execbuf.flags = I915_EXEC_USE_EXTENSIONS;
> +       execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
> +       execbuf.num_cliprects = 0;
> +
> +       memset(&obj, 0, sizeof(obj));
> +       obj.handle = gem_create(fd, 4096);
> +       gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
> +
> +       fence.flags = I915_EXEC_FENCE_SIGNAL;
> +       gem_execbuf(fd, &execbuf);
> +
> +       igt_assert(gem_bo_busy(fd, obj.handle));
> +       igt_assert(syncobj_busy(fd, fence.handle));
> +
> +       igt_spin_free(fd, spin);
> +
> +       gem_sync(fd, obj.handle);
> +       igt_assert(!gem_bo_busy(fd, obj.handle));
> +       igt_assert(!syncobj_busy(fd, fence.handle));

I'd reverse the order of these asserts - we waited on the handle, so we
first assert the syncobj. And I'd have another test that waited on the
syncobj and assert the obj.handle was idle (maybe you already do).
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 09/10] lib/i915: add mmio base for engines
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 09/10] lib/i915: add mmio base for engines Lionel Landwerlin
@ 2019-11-20 21:42   ` Chris Wilson
  2019-11-21 13:15     ` Lionel Landwerlin
  0 siblings, 1 reply; 24+ messages in thread
From: Chris Wilson @ 2019-11-20 21:42 UTC (permalink / raw)
  To: Lionel Landwerlin, igt-dev

Quoting Lionel Landwerlin (2019-11-20 21:21:42)
> Useful when you want to work with MI_ALU and general purpose registers
> local to an engine.
> 
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> ---
>  lib/i915/gem_engine_topology.c | 74 ++++++++++++++++++++++++++++++++++
>  lib/i915/gem_engine_topology.h |  5 +++
>  2 files changed, 79 insertions(+)
> 
> diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
> index 790d455f..925fdb51 100644
> --- a/lib/i915/gem_engine_topology.c
> +++ b/lib/i915/gem_engine_topology.c
> @@ -22,6 +22,7 @@
>   */
>  
>  #include "drmtest.h"
> +#include "intel_chipset.h"
>  #include "ioctl_wrappers.h"
>  
>  #include "i915/gem_engine_topology.h"
> @@ -337,3 +338,76 @@ bool gem_engine_is_equal(const struct intel_execution_engine2 *e1,
>  {
>         return e1->class == e2->class && e1->instance == e2->instance;
>  }
> +
> +uint32_t intel_get_engine_mmio_base(const uint16_t devid,
> +                                   const struct intel_execution_engine2 *e)
> +{
> +       switch (e->class) {
> +       case I915_ENGINE_CLASS_RENDER:
> +               return 0x2000;
> +       case I915_ENGINE_CLASS_COPY:
> +               return 0x22000;
> +       case I915_ENGINE_CLASS_VIDEO: {
> +               uint32_t gen11_bases[] = {
> +                       0x1c0000,

Physical layout is not possible to determine from class/inst nor legacy
I915_EXEC_RING.

https://patchwork.freedesktop.org/patch/340599/?series=69401&rev=1
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 01/10] lib/syncobj: drop local declarations
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 01/10] lib/syncobj: drop local declarations Lionel Landwerlin
@ 2019-11-20 21:49   ` Chris Wilson
  0 siblings, 0 replies; 24+ messages in thread
From: Chris Wilson @ 2019-11-20 21:49 UTC (permalink / raw)
  To: Lionel Landwerlin, igt-dev

Quoting Lionel Landwerlin (2019-11-20 21:21:34)
> We have copies of the DRM uAPI headers in the repo, so drop the local
> declaration of syncobj defines/types.
> 
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> ---
>  lib/igt_syncobj.c     | 16 ++++++------
>  lib/igt_syncobj.h     | 26 +------------------
>  tests/syncobj_basic.c |  2 +-
>  tests/syncobj_wait.c  | 58 +++++++++++++++++++++----------------------
>  4 files changed, 39 insertions(+), 63 deletions(-)
> 
> diff --git a/lib/igt_syncobj.c b/lib/igt_syncobj.c
> index 0fddb97a..e5569ffc 100644
> --- a/lib/igt_syncobj.c
> +++ b/lib/igt_syncobj.c
> @@ -170,10 +170,10 @@ syncobj_import_sync_file(int fd, uint32_t handle, int sync_file)
>  }
>  
>  int
> -__syncobj_wait(int fd, struct local_syncobj_wait *args)
> +__syncobj_wait(int fd, struct drm_syncobj_wait *args)
>  {
>         int err = 0;
> -       if (drmIoctl(fd, LOCAL_IOCTL_SYNCOBJ_WAIT, args))
> +       if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_WAIT, args))

s/drmIoctl/igt_ioctl/ as well, just in case we ever want to do signal
injection or measure latencies.

>                 err = -errno;

When we return err, clear errno -- it just muddies up the igt_assert()
if we already know it.

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 02/10] drm-uapi: Update drm headers to 17cc51390c141662748dbbc2fe98f3ed10f2e13e
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 02/10] drm-uapi: Update drm headers to 17cc51390c141662748dbbc2fe98f3ed10f2e13e Lionel Landwerlin
@ 2019-11-20 21:50   ` Chris Wilson
  2019-11-21 11:10     ` Lionel Landwerlin
  0 siblings, 1 reply; 24+ messages in thread
From: Chris Wilson @ 2019-11-20 21:50 UTC (permalink / raw)
  To: Lionel Landwerlin, igt-dev

Quoting Lionel Landwerlin (2019-11-20 21:21:35)
>   commit 17cc51390c141662748dbbc2fe98f3ed10f2e13e
>   Merge: 2d0720f5a4fc b4011644b03c
>   Author: Dave Airlie <airlied@redhat.com>
>   Date:   Fri Nov 15 12:34:39 2019 +1000
> 
>       Merge branch 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux into drm-next
> 
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>

Looks sane, didn't actually check as the next headers_install will fixup
any mistakes :)
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 05/10] tests/i915/exec_fence: switch to internal headers
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 05/10] tests/i915/exec_fence: switch to internal headers Lionel Landwerlin
@ 2019-11-20 21:51   ` Chris Wilson
  0 siblings, 0 replies; 24+ messages in thread
From: Chris Wilson @ 2019-11-20 21:51 UTC (permalink / raw)
  To: Lionel Landwerlin, igt-dev

Quoting Lionel Landwerlin (2019-11-20 21:21:38)
> Drop local defines etc..
> 
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 06/10] tests/i915/exec_fence: reuse syncobj helpers
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 06/10] tests/i915/exec_fence: reuse syncobj helpers Lionel Landwerlin
@ 2019-11-20 21:52   ` Chris Wilson
  0 siblings, 0 replies; 24+ messages in thread
From: Chris Wilson @ 2019-11-20 21:52 UTC (permalink / raw)
  To: Lionel Landwerlin, igt-dev

Quoting Lionel Landwerlin (2019-11-20 21:21:39)
> v2: Fix mistake in syncobj_busy() (Lionel)
> 
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>

Ok, but the asserts from the lib/ had better be intelligible...
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 10/10] tests/i915/gem_exec_fence: add engine chaining tests
  2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 10/10] tests/i915/gem_exec_fence: add engine chaining tests Lionel Landwerlin
@ 2019-11-20 22:02   ` Chris Wilson
  0 siblings, 0 replies; 24+ messages in thread
From: Chris Wilson @ 2019-11-20 22:02 UTC (permalink / raw)
  To: Lionel Landwerlin, igt-dev

Quoting Lionel Landwerlin (2019-11-20 21:21:43)
> +static void test_syncobj_timeline_chain_engines(int fd, struct intel_engine_data *engines)
> +{
...
> +       gem_sync(fd, ctx.engine_counter_object.handle);
> +
> +       counter_output = gem_mmap__wc(fd, ctx.engine_counter_object.handle, 0, 4096, PROT_READ);
> +
> +       for (uint32_t i = 0; i < ctx.engines->nengines; i++)
> +               igt_debug("engine %i (%s)\t= %016lx\n", i,
> +                         ctx.engines->engines[i].name, counter_output[i]);
> +
> +       /*
> +        * Verify that we get the fibonacci number expected (we start
> +        * at the sequence on the second number : 1).
> +        */
> +       igt_assert_eq(counter_output[engines->nengines - 1],
> +                     fib(ARRAY_SIZE(ctx.iterations) * engines->nengines + 1));
> +
> +       teardown_timeline_chain_engines(&ctx);
> +}
> +
> +static void test_syncobj_stationary_timeline_chain_engines(int fd, struct intel_engine_data *engines)
> +{
...
> +       gem_sync(fd, ctx.engine_counter_object.handle);
> +
> +       counter_output = gem_mmap__wc(fd, ctx.engine_counter_object.handle, 0, 4096, PROT_READ);
> +
> +       for (uint32_t i = 0; i < ctx.engines->nengines; i++)
> +               igt_debug("engine %i (%s)\t= %016lx\n", i,
> +                         ctx.engines->engines[i].name, counter_output[i]);
> +       igt_assert_eq(counter_output[engines->nengines - 1],
> +                     fib(ARRAY_SIZE(ctx.iterations) * engines->nengines + 1));
> +
> +       teardown_timeline_chain_engines(&ctx);
> +}
> +
> +static void test_syncobj_backward_timeline_chain_engines(int fd, struct intel_engine_data *engines)
> +{
...
> +       gem_sync(fd, ctx.engine_counter_object.handle);
> +
> +       counter_output = gem_mmap__wc(fd, ctx.engine_counter_object.handle, 0, 4096, PROT_READ);
> +
> +       for (uint32_t i = 0; i < ctx.engines->nengines; i++)
> +               igt_debug("engine %i (%s)\t= %016lx\n", i,
> +                         ctx.engines->engines[i].name, counter_output[i]);
> +       igt_assert_eq(counter_output[engines->nengines - 1],
> +                     fib(ARRAY_SIZE(ctx.iterations) * engines->nengines + 1));

You probably want to invest in a few munmap...
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [igt-dev] ✗ GitLab.Pipeline: warning for tests: Add timeline syncobj testing
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
                   ` (8 preceding siblings ...)
       [not found] ` <20191120212143.364333-5-lionel.g.landwerlin@intel.com>
@ 2019-11-20 23:02 ` Patchwork
  2019-11-20 23:42 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Patchwork @ 2019-11-20 23:02 UTC (permalink / raw)
  To: Lionel Landwerlin; +Cc: igt-dev

== Series Details ==

Series: tests: Add timeline syncobj testing
URL   : https://patchwork.freedesktop.org/series/69782/
State : warning

== Summary ==

Did not get list of undocumented tests for this run, something is wrong!

Other than that, pipeline status: FAILED.

see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/pipelines/81122 for the overview.

== Logs ==

For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/pipelines/81122
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [igt-dev] ✓ Fi.CI.BAT: success for tests: Add timeline syncobj testing
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
                   ` (9 preceding siblings ...)
  2019-11-20 23:02 ` [igt-dev] ✗ GitLab.Pipeline: warning for tests: Add timeline syncobj testing Patchwork
@ 2019-11-20 23:42 ` Patchwork
       [not found] ` <20191120212143.364333-4-lionel.g.landwerlin@intel.com>
  2019-11-21 22:16 ` [igt-dev] ✓ Fi.CI.IGT: success for tests: Add timeline syncobj testing Patchwork
  12 siblings, 0 replies; 24+ messages in thread
From: Patchwork @ 2019-11-20 23:42 UTC (permalink / raw)
  To: Lionel Landwerlin; +Cc: igt-dev

== Series Details ==

Series: tests: Add timeline syncobj testing
URL   : https://patchwork.freedesktop.org/series/69782/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_7393 -> IGTPW_3738
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/index.html

Known issues
------------

  Here are the changes found in IGTPW_3738 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_module_load@reload-no-display:
    - fi-skl-lmem:        [PASS][1] -> [DMESG-WARN][2] ([fdo#112261])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/fi-skl-lmem/igt@i915_module_load@reload-no-display.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/fi-skl-lmem/igt@i915_module_load@reload-no-display.html

  * igt@i915_pm_rpm@module-reload:
    - fi-skl-6770hq:      [PASS][3] -> [FAIL][4] ([fdo#108511])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/fi-skl-6770hq/igt@i915_pm_rpm@module-reload.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/fi-skl-6770hq/igt@i915_pm_rpm@module-reload.html

  
#### Possible fixes ####

  * igt@kms_frontbuffer_tracking@basic:
    - fi-icl-u3:          [FAIL][5] ([fdo#103167]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/fi-icl-u3/igt@kms_frontbuffer_tracking@basic.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/fi-icl-u3/igt@kms_frontbuffer_tracking@basic.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#108511]: https://bugs.freedesktop.org/show_bug.cgi?id=108511
  [fdo#109964]: https://bugs.freedesktop.org/show_bug.cgi?id=109964
  [fdo#112261]: https://bugs.freedesktop.org/show_bug.cgi?id=112261
  [fdo#112298]: https://bugs.freedesktop.org/show_bug.cgi?id=112298


Participating hosts (50 -> 45)
------------------------------

  Missing    (5): fi-hsw-4200u fi-bsw-cyan fi-ctg-p8600 fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5299 -> IGTPW_3738

  CI-20190529: 20190529
  CI_DRM_7393: 0e204eb18baca0cd97950bf936fffdbbce1fd337 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_3738: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/index.html
  IGT_5299: 65fed6a79adea14f7bef6d55530da47d7731d370 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+++ 132 lines
--- 0 lines

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 02/10] drm-uapi: Update drm headers to 17cc51390c141662748dbbc2fe98f3ed10f2e13e
  2019-11-20 21:50   ` Chris Wilson
@ 2019-11-21 11:10     ` Lionel Landwerlin
  0 siblings, 0 replies; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-21 11:10 UTC (permalink / raw)
  To: Chris Wilson, igt-dev

On 20/11/2019 23:50, Chris Wilson wrote:
> Quoting Lionel Landwerlin (2019-11-20 21:21:35)
>>    commit 17cc51390c141662748dbbc2fe98f3ed10f2e13e
>>    Merge: 2d0720f5a4fc b4011644b03c
>>    Author: Dave Airlie <airlied@redhat.com>
>>    Date:   Fri Nov 15 12:34:39 2019 +1000
>>
>>        Merge branch 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux into drm-next
>>
>> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> Looks sane, didn't actually check as the next headers_install will fixup
> any mistakes :)
> Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
> -Chris

It's worth noting that Tvrtko added drm_fourc.h Gen12 stuff that isn't 
in drm-next yet.

So I left what he put other things don't compile.


-Lionel

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 09/10] lib/i915: add mmio base for engines
  2019-11-20 21:42   ` Chris Wilson
@ 2019-11-21 13:15     ` Lionel Landwerlin
  0 siblings, 0 replies; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-21 13:15 UTC (permalink / raw)
  To: Chris Wilson, igt-dev

On 20/11/2019 23:42, Chris Wilson wrote:
> Quoting Lionel Landwerlin (2019-11-20 21:21:42)
>> Useful when you want to work with MI_ALU and general purpose registers
>> local to an engine.
>>
>> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>> ---
>>   lib/i915/gem_engine_topology.c | 74 ++++++++++++++++++++++++++++++++++
>>   lib/i915/gem_engine_topology.h |  5 +++
>>   2 files changed, 79 insertions(+)
>>
>> diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
>> index 790d455f..925fdb51 100644
>> --- a/lib/i915/gem_engine_topology.c
>> +++ b/lib/i915/gem_engine_topology.c
>> @@ -22,6 +22,7 @@
>>    */
>>   
>>   #include "drmtest.h"
>> +#include "intel_chipset.h"
>>   #include "ioctl_wrappers.h"
>>   
>>   #include "i915/gem_engine_topology.h"
>> @@ -337,3 +338,76 @@ bool gem_engine_is_equal(const struct intel_execution_engine2 *e1,
>>   {
>>          return e1->class == e2->class && e1->instance == e2->instance;
>>   }
>> +
>> +uint32_t intel_get_engine_mmio_base(const uint16_t devid,
>> +                                   const struct intel_execution_engine2 *e)
>> +{
>> +       switch (e->class) {
>> +       case I915_ENGINE_CLASS_RENDER:
>> +               return 0x2000;
>> +       case I915_ENGINE_CLASS_COPY:
>> +               return 0x22000;
>> +       case I915_ENGINE_CLASS_VIDEO: {
>> +               uint32_t gen11_bases[] = {
>> +                       0x1c0000,
> Physical layout is not possible to determine from class/inst nor legacy
> I915_EXEC_RING.
>
> https://patchwork.freedesktop.org/patch/340599/?series=69401&rev=1
> -Chris

What are my options? Landing your sysfs series (which looks pretty good) 
first?

Is the fact this is part of the unstable api going to be a problem for CI?


Thanks,


-Lionel

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 03/10] igt: add timeline test cases
       [not found] ` <20191120212143.364333-4-lionel.g.landwerlin@intel.com>
@ 2019-11-21 14:07   ` Petri Latvala
  2019-11-22 13:03     ` Lionel Landwerlin
  0 siblings, 1 reply; 24+ messages in thread
From: Petri Latvala @ 2019-11-21 14:07 UTC (permalink / raw)
  To: Lionel Landwerlin; +Cc: igt-dev, Chunming Zhou

On Wed, Nov 20, 2019 at 11:21:36PM +0200, Lionel Landwerlin wrote:
> From: Chunming Zhou <david1.zhou@amd.com>
> 
> v2: adapt to new transfer ioctl
> 
> v3: Drop useless uint64_t casts (Lionel)
>     Fix timeline query prototypes (Lionel)
>     Test multi wait with timeline & binary syncobjs (Lionel)
> 
> v4: Switch from drmIoctl to igt_ioctl in tests/*.c (Chris)
>     Clear out errno in helper functions (Chris)
> 
> v5: Fix lib comments on transfer helpers (Lionel)
> 
> v6: Add igt_describe() (Lionel)
> 
> Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> ---
>  lib/igt_syncobj.c        |  237 ++++++++
>  lib/igt_syncobj.h        |   19 +
>  tests/meson.build        |    1 +

Corresponding autotools change missing.


-- 
Petri Latvala



>  tests/syncobj_timeline.c | 1150 ++++++++++++++++++++++++++++++++++++++
>  4 files changed, 1407 insertions(+)
>  create mode 100644 tests/syncobj_timeline.c
> 
> diff --git a/lib/igt_syncobj.c b/lib/igt_syncobj.c
> index e5569ffc..632a5182 100644
> --- a/lib/igt_syncobj.c
> +++ b/lib/igt_syncobj.c
> @@ -286,3 +286,240 @@ syncobj_signal(int fd, uint32_t *handles, uint32_t count)
>  {
>  	igt_assert_eq(__syncobj_signal(fd, handles, count), 0);
>  }
> +
> +static int
> +__syncobj_timeline_signal(int fd, uint32_t *handles, uint64_t *points, uint32_t count)
> +{
> +	struct drm_syncobj_timeline_array array = { 0 };
> +	int err = 0;
> +
> +	array.handles = to_user_pointer(handles);
> +	array.points = to_user_pointer(points);
> +	array.count_handles = count;
> +	if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &array)) {
> +		err = -errno;
> +		igt_assume(err);
> +	}
> +	errno = 0;
> +	return err;
> +}
> +
> +/**
> + * syncobj_signal:
> + * @fd: The DRM file descriptor.
> + * @handles: Array of syncobj handles to signal
> + * @points: List of point of handles to signal.
> + * @count: Count of syncobj handles.
> + *
> + * Signal a set of syncobjs.
> + */
> +void
> +syncobj_timeline_signal(int fd, uint32_t *handles, uint64_t *points, uint32_t count)
> +{
> +	igt_assert_eq(__syncobj_timeline_signal(fd, handles, points, count), 0);
> +}
> +int
> +__syncobj_timeline_wait_ioctl(int fd, struct drm_syncobj_timeline_wait *args)
> +{
> +	int err = 0;
> +	if (drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, args)) {
> +		err = -errno;
> +		igt_assume(err);
> +	}
> +	errno = 0;
> +	return err;
> +}
> +static int
> +__syncobj_timeline_wait(int fd, uint32_t *handles, uint64_t *points,
> +			unsigned num_handles,
> +			int64_t timeout_nsec, unsigned flags,
> +			uint32_t *first_signaled)
> +{
> +	struct drm_syncobj_timeline_wait args;
> +	int ret;
> +
> +	args.handles = to_user_pointer(handles);
> +	args.points = to_user_pointer(points);
> +	args.timeout_nsec = timeout_nsec;
> +	args.count_handles = num_handles;
> +	args.flags = flags;
> +	args.first_signaled = 0;
> +	args.pad = 0;
> +
> +	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &args);
> +	if (ret < 0) {
> +		ret = -errno;
> +		igt_assume(ret);
> +	}
> +	errno = 0;
> +
> +	if (first_signaled)
> +		*first_signaled = args.first_signaled;
> +
> +	return ret;
> +}
> +int
> +syncobj_timeline_wait_err(int fd, uint32_t *handles, uint64_t *points,
> +			  unsigned num_handles,
> +			  int64_t timeout_nsec, unsigned flags)
> +{
> +	return __syncobj_timeline_wait(fd, handles, points, num_handles,
> +				       timeout_nsec, flags, NULL);
> +}
> +
> +/**
> + * syncobj_timeline_wait:
> + * @fd: The DRM file descriptor
> + * @handles: List of syncobj handles to wait for.
> + * @points: List of point of handles to wait for.
> + * @num_handles: Count of handles
> + * @timeout_nsec: Absolute wait timeout in nanoseconds.
> + * @flags: Wait ioctl flags.
> + * @first_signaled: Returned handle for first signaled syncobj.
> + *
> + * Waits in the kernel for any/all the requested syncobjs timeline point
> + * using the timeout and flags.
> + * Returns: bool value - false = timedout, true = signaled
> + */
> +bool
> +syncobj_timeline_wait(int fd, uint32_t *handles, uint64_t *points,
> +		      unsigned num_handles,
> +		      int64_t timeout_nsec, unsigned flags,
> +		      uint32_t *first_signaled)
> +{
> +	int ret;
> +
> +	ret = __syncobj_timeline_wait(fd, handles, points, num_handles,
> +				      timeout_nsec, flags, first_signaled);
> +	if (ret == -ETIME)
> +		return false;
> +	igt_assert_eq(ret, 0);
> +
> +	return true;
> +
> +}
> +
> +static int
> +__syncobj_timeline_query(int fd, uint32_t *handles, uint64_t *points,
> +			 uint32_t handle_count)
> +{
> +	struct drm_syncobj_timeline_array args;
> +	int ret;
> +
> +	args.handles = to_user_pointer(handles);
> +	args.points = to_user_pointer(points);
> +	args.count_handles = handle_count;
> +	args.flags = 0;
> +
> +	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
> +	if (ret) {
> +		ret = -errno;
> +		igt_assume(ret);
> +	}
> +
> +	errno = 0;
> +	return ret;
> +}
> +
> +/**
> + * syncobj_timeline_query:
> + * @fd: The DRM file descriptor.
> + * @handles: Array of syncobj handles.
> + * @points: Array of syncobj points queried.
> + * @count: Count of syncobj handles.
> + *
> + * Queries a set of syncobjs.
> + */
> +void
> +syncobj_timeline_query(int fd, uint32_t *handles, uint64_t *points,
> +		       uint32_t count)
> +{
> +	igt_assert_eq(__syncobj_timeline_query(fd, handles, points, count), 0);
> +}
> +
> +static int
> +__syncobj_binary_to_timeline(int fd, uint32_t timeline_handle,
> +			     uint64_t point, uint32_t binary_handle)
> +{
> +	struct drm_syncobj_transfer args;
> +	int ret;
> +
> +	args.src_handle = binary_handle;
> +	args.dst_handle = timeline_handle;
> +	args.src_point = 0;
> +	args.dst_point = point;
> +	args.flags = 0;
> +	args.pad = 0;
> +	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
> +	if (ret) {
> +		ret = -errno;
> +		igt_assert(ret);
> +	}
> +
> +	errno = 0;
> +	return ret;
> +}
> +
> +/**
> + * syncobj_binary_to_timeline:
> + * @fd: The DRM file descriptor.
> + * @timeline_handle: A syncobj timeline handle
> + * @point: A syncobj timeline point in the timeline handle
> + * @binary_handle: A syncobj binary handle
> + *
> + * Transfers a DMA fence from a binary syncobj into a timeline syncobj
> + * at a given point on the timeline.
> + */
> +void
> +syncobj_binary_to_timeline(int fd, uint32_t timeline_handle,
> +			   uint64_t point, uint32_t binary_handle)
> +{
> +	igt_assert_eq(__syncobj_binary_to_timeline(fd, timeline_handle, point,
> +						   binary_handle), 0);
> +}
> +
> +static int
> +__syncobj_timeline_to_binary(int fd, uint32_t binary_handle,
> +			     uint32_t timeline_handle,
> +			     uint64_t point,
> +			     uint32_t flags)
> +{
> +	struct drm_syncobj_transfer args;
> +	int ret;
> +
> +	args.dst_handle = binary_handle;
> +	args.src_handle = timeline_handle;
> +	args.dst_point = 0;
> +	args.src_point = point;
> +	args.flags = flags;
> +	args.pad = 0;
> +	ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
> +	if (ret) {
> +		ret = -errno;
> +		igt_assert(ret);
> +	}
> +
> +	errno = 0;
> +	return ret;
> +}
> +
> +/**
> + * syncobj_binary_to_timeline:
> + * @fd: The DRM file descriptor.
> + * @binary_handle: A syncobj binary handle
> + * @timeline_handle: A syncobj timeline handle
> + * @point: A syncobj timeline point in the timeline handle
> + *
> + * Transfers DMA fence from a given point from timeline syncobj into a
> + * binary syncobj.
> + */
> +void
> +syncobj_timeline_to_binary(int fd, uint32_t binary_handle,
> +			   uint32_t timeline_handle,
> +			   uint64_t point,
> +			   uint32_t flags)
> +{
> +	igt_assert_eq(__syncobj_timeline_to_binary(fd, binary_handle,
> +						   timeline_handle, point,
> +						   flags), 0);
> +}
> diff --git a/lib/igt_syncobj.h b/lib/igt_syncobj.h
> index 51ad2364..20f1f18f 100644
> --- a/lib/igt_syncobj.h
> +++ b/lib/igt_syncobj.h
> @@ -41,7 +41,26 @@ int syncobj_wait_err(int fd, uint32_t *handles, uint32_t count,
>  bool syncobj_wait(int fd, uint32_t *handles, uint32_t count,
>  		  uint64_t abs_timeout_nsec, uint32_t flags,
>  		  uint32_t *first_signaled);
> +int __syncobj_timeline_wait_ioctl(int fd,
> +				  struct drm_syncobj_timeline_wait *args);
> +bool syncobj_timeline_wait(int fd, uint32_t *handles, uint64_t *points,
> +			   unsigned num_handles,
> +			   int64_t timeout_nsec, unsigned flags,
> +			   uint32_t *first_signaled);
> +int syncobj_timeline_wait_err(int fd, uint32_t *handles, uint64_t *points,
> +			      unsigned num_handles,
> +			      int64_t timeout_nsec, unsigned flags);
>  void syncobj_reset(int fd, uint32_t *handles, uint32_t count);
>  void syncobj_signal(int fd, uint32_t *handles, uint32_t count);
> +void syncobj_timeline_query(int fd, uint32_t *handles, uint64_t *points,
> +			    uint32_t count);
> +void syncobj_binary_to_timeline(int fd, uint32_t timeline_handle,
> +				uint64_t point, uint32_t binary_handle);
> +void syncobj_timeline_to_binary(int fd, uint32_t binary_handle,
> +				uint32_t timeline_handle,
> +				uint64_t point,
> +				uint32_t flags);
> +void syncobj_timeline_signal(int fd, uint32_t *handles, uint64_t *points,
> +			     uint32_t count);
>  
>  #endif /* IGT_SYNCOBJ_H */
> diff --git a/tests/meson.build b/tests/meson.build
> index 755fc9e6..7ed4140b 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -82,6 +82,7 @@ test_progs = [
>  	'prime_vgem',
>  	'syncobj_basic',
>  	'syncobj_wait',
> +	'syncobj_timeline',
>  	'template',
>  	'tools_test',
>  	'v3d_get_bo_offset',
> diff --git a/tests/syncobj_timeline.c b/tests/syncobj_timeline.c
> new file mode 100644
> index 00000000..82fc08aa
> --- /dev/null
> +++ b/tests/syncobj_timeline.c
> @@ -0,0 +1,1150 @@
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + */
> +
> +#include "igt.h"
> +#include "sw_sync.h"
> +#include "igt_syncobj.h"
> +#include <unistd.h>
> +#include <time.h>
> +#include <sys/ioctl.h>
> +#include <pthread.h>
> +#include <signal.h>
> +#include "drm.h"
> +
> +IGT_TEST_DESCRIPTION("Tests for the drm timeline sync object API");
> +
> +/* One tenth of a second */
> +#define SHORT_TIME_NSEC 100000000ull
> +
> +#define NSECS_PER_SEC 1000000000ull
> +
> +static uint64_t
> +gettime_ns(void)
> +{
> +	struct timespec current;
> +	clock_gettime(CLOCK_MONOTONIC, &current);
> +	return (uint64_t)current.tv_sec * NSECS_PER_SEC + current.tv_nsec;
> +}
> +
> +static void
> +sleep_nsec(uint64_t time_nsec)
> +{
> +	struct timespec t;
> +	t.tv_sec = time_nsec / NSECS_PER_SEC;
> +	t.tv_nsec = time_nsec % NSECS_PER_SEC;
> +	igt_assert_eq(nanosleep(&t, NULL), 0);
> +}
> +
> +static uint64_t
> +short_timeout(void)
> +{
> +	return gettime_ns() + SHORT_TIME_NSEC;
> +}
> +
> +static int
> +syncobj_attach_sw_sync(int fd, uint32_t handle, uint64_t point)
> +{
> +	int timeline, fence;
> +
> +	timeline = sw_sync_timeline_create();
> +	fence = sw_sync_timeline_create_fence(timeline, 1);
> +
> +	if (point == 0) {
> +		syncobj_import_sync_file(fd, handle, fence);
> +	} else {
> +		uint32_t syncobj = syncobj_create(fd, 0);
> +
> +		syncobj_import_sync_file(fd, syncobj, fence);
> +		syncobj_binary_to_timeline(fd, handle, point, syncobj);
> +		syncobj_destroy(fd, syncobj);
> +	}
> +
> +	close(fence);
> +
> +	return timeline;
> +}
> +
> +static void
> +syncobj_trigger(int fd, uint32_t handle, uint64_t point)
> +{
> +	int timeline = syncobj_attach_sw_sync(fd, handle, point);
> +	sw_sync_timeline_inc(timeline, 1);
> +	close(timeline);
> +}
> +
> +static timer_t
> +set_timer(void (*cb)(union sigval), void *ptr, int i, uint64_t nsec)
> +{
> +        timer_t timer;
> +        struct sigevent sev;
> +        struct itimerspec its;
> +
> +        memset(&sev, 0, sizeof(sev));
> +        sev.sigev_notify = SIGEV_THREAD;
> +	if (ptr)
> +		sev.sigev_value.sival_ptr = ptr;
> +	else
> +		sev.sigev_value.sival_int = i;
> +        sev.sigev_notify_function = cb;
> +        igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
> +
> +        memset(&its, 0, sizeof(its));
> +        its.it_value.tv_sec = nsec / NSEC_PER_SEC;
> +        its.it_value.tv_nsec = nsec % NSEC_PER_SEC;
> +        igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
> +
> +	return timer;
> +}
> +
> +struct fd_handle_pair {
> +	int fd;
> +	uint32_t handle;
> +	uint64_t point;
> +};
> +
> +static void
> +timeline_inc_func(union sigval sigval)
> +{
> +	sw_sync_timeline_inc(sigval.sival_int, 1);
> +}
> +
> +static void
> +syncobj_trigger_free_pair_func(union sigval sigval)
> +{
> +	struct fd_handle_pair *pair = sigval.sival_ptr;
> +	syncobj_trigger(pair->fd, pair->handle, pair->point);
> +	free(pair);
> +}
> +
> +static timer_t
> +syncobj_trigger_delayed(int fd, uint32_t syncobj, uint64_t point, uint64_t nsec)
> +{
> +	struct fd_handle_pair *pair = malloc(sizeof(*pair));
> +
> +	pair->fd = fd;
> +	pair->handle = syncobj;
> +	pair->point = point;
> +
> +	return set_timer(syncobj_trigger_free_pair_func, pair, 0, nsec);
> +}
> +
> +static const char *test_wait_bad_flags_desc =
> +	"Verifies that an invalid value in drm_syncobj_timeline_wait::flags is"
> +	" rejected";
> +static void
> +test_wait_bad_flags(int fd)
> +{
> +	struct drm_syncobj_timeline_wait wait = {};
> +	wait.flags = 0xdeadbeef;
> +	igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -EINVAL);
> +}
> +
> +static const char *test_wait_zero_handles_desc =
> +	"Verifies that waiting on an empty list of invalid syncobj handles is"
> +	" rejected";
> +static void
> +test_wait_zero_handles(int fd)
> +{
> +	struct drm_syncobj_timeline_wait wait = {};
> +	igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -EINVAL);
> +}
> +
> +static const char *test_wait_illegal_handle_desc =
> +	"Verifies that waiting on an invalid syncobj handle is rejected";
> +static void
> +test_wait_illegal_handle(int fd)
> +{
> +	struct drm_syncobj_timeline_wait wait = {};
> +	uint32_t handle = 0;
> +
> +	wait.count_handles = 1;
> +	wait.handles = to_user_pointer(&handle);
> +	igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -ENOENT);
> +}
> +
> +static const char *test_query_zero_handles_desc =
> +	"Verifies that querying an empty list of syncobj handles is rejected";
> +static void
> +test_query_zero_handles(int fd)
> +{
> +	struct drm_syncobj_timeline_array args = {};
> +	int ret;
> +
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
> +	igt_assert(ret == -1 && errno ==  EINVAL);
> +}
> +
> +static const char *test_query_illegal_handle_desc =
> +	"Verifies that querying an invalid syncobj handle is rejected";
> +static void
> +test_query_illegal_handle(int fd)
> +{
> +	struct drm_syncobj_timeline_array args = {};
> +	uint32_t handle = 0;
> +	int ret;
> +
> +	args.count_handles = 1;
> +	args.handles = to_user_pointer(&handle);
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
> +	igt_assert(ret == -1 && errno == ENOENT);
> +}
> +
> +static const char *test_query_one_illegal_handle_desc =
> +	"Verifies that querying a list of invalid syncobj handle including an"
> +	" invalid one is rejected";
> +static void
> +test_query_one_illegal_handle(int fd)
> +{
> +	struct drm_syncobj_timeline_array array = {};
> +	uint32_t syncobjs[3];
> +	uint64_t initial_point = 1;
> +	int ret;
> +
> +	syncobjs[0] = syncobj_create(fd, 0);
> +	syncobjs[1] = 0;
> +	syncobjs[2] = syncobj_create(fd, 0);
> +
> +	syncobj_timeline_signal(fd, &syncobjs[0], &initial_point, 1);
> +	syncobj_timeline_signal(fd, &syncobjs[2], &initial_point, 1);
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[0],
> +						&initial_point, 1, 0, 0), 0);
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[2],
> +						&initial_point, 1, 0, 0), 0);
> +
> +	array.count_handles = 3;
> +	array.handles = to_user_pointer(syncobjs);
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &array);
> +	igt_assert(ret == -1 && errno == ENOENT);
> +
> +	syncobj_destroy(fd, syncobjs[0]);
> +	syncobj_destroy(fd, syncobjs[2]);
> +}
> +
> +static const char *test_query_bad_pad_desc =
> +	"Verify that querying a timeline syncobj with an invalid"
> +	" drm_syncobj_timeline_array::flags field is rejected";
> +static void
> +test_query_bad_pad(int fd)
> +{
> +	struct drm_syncobj_timeline_array array = {};
> +	uint32_t handle = 0;
> +	int ret;
> +
> +	array.flags = 0xdeadbeef;
> +	array.count_handles = 1;
> +	array.handles = to_user_pointer(&handle);
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &array);
> +	igt_assert(ret == -1 && errno == EINVAL);
> +}
> +
> +static const char *test_signal_zero_handles_desc =
> +	"Verify that signaling an empty list of syncobj handles is rejected";
> +static void
> +test_signal_zero_handles(int fd)
> +{
> +	struct drm_syncobj_timeline_array args = {};
> +	int ret;
> +
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
> +	igt_assert(ret == -1 && errno ==  EINVAL);
> +}
> +
> +static const char *test_signal_illegal_handle_desc =
> +	"Verify that signaling an invalid syncobj handle is rejected";
> +static void
> +test_signal_illegal_handle(int fd)
> +{
> +	struct drm_syncobj_timeline_array args = {};
> +	uint32_t handle = 0;
> +	int ret;
> +
> +	args.count_handles = 1;
> +	args.handles = to_user_pointer(&handle);
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
> +	igt_assert(ret == -1 && errno == ENOENT);
> +}
> +
> +static void
> +test_signal_illegal_point(int fd)
> +{
> +	struct drm_syncobj_timeline_array args = {};
> +	uint32_t handle = 1;
> +	uint64_t point = 0;
> +	int ret;
> +
> +	args.count_handles = 1;
> +	args.handles = to_user_pointer(&handle);
> +	args.points = to_user_pointer(&point);
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
> +	igt_assert(ret == -1 && errno == ENOENT);
> +}
> +
> +static const char *test_signal_one_illegal_handle_desc =
> +	"Verify that an invalid syncobj handle in drm_syncobj_timeline_array is"
> +	" rejected for signaling";
> +static void
> +test_signal_one_illegal_handle(int fd)
> +{
> +	struct drm_syncobj_timeline_array array = {};
> +	uint32_t syncobjs[3];
> +	uint64_t initial_point = 1;
> +	int ret;
> +
> +	syncobjs[0] = syncobj_create(fd, 0);
> +	syncobjs[1] = 0;
> +	syncobjs[2] = syncobj_create(fd, 0);
> +
> +	syncobj_timeline_signal(fd, &syncobjs[0], &initial_point, 1);
> +	syncobj_timeline_signal(fd, &syncobjs[2], &initial_point, 1);
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[0],
> +						&initial_point, 1, 0, 0), 0);
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[2],
> +						&initial_point, 1, 0, 0), 0);
> +
> +	array.count_handles = 3;
> +	array.handles = to_user_pointer(syncobjs);
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &array);
> +	igt_assert(ret == -1 && errno == ENOENT);
> +
> +	syncobj_destroy(fd, syncobjs[0]);
> +	syncobj_destroy(fd, syncobjs[2]);
> +}
> +
> +static const char *test_signal_bad_pad_desc =
> +	"Verifies that an invalid value in drm_syncobj_timeline_array.flags is"
> +	" rejected";
> +static void
> +test_signal_bad_pad(int fd)
> +{
> +	struct drm_syncobj_timeline_array array = {};
> +	uint32_t handle = 0;
> +	int ret;
> +
> +	array.flags = 0xdeadbeef;
> +	array.count_handles = 1;
> +	array.handles = to_user_pointer(&handle);
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &array);
> +	igt_assert(ret == -1 && errno == EINVAL);
> +}
> +
> +static const char *test_signal_array_desc =
> +	"Verifies the signaling of a list of timeline syncobj";
> +static void
> +test_signal_array(int fd)
> +{
> +	uint32_t syncobjs[4];
> +	uint64_t points[4] = {1, 1, 1, 0};
> +
> +	syncobjs[0] = syncobj_create(fd, 0);
> +	syncobjs[1] = syncobj_create(fd, 0);
> +	syncobjs[2] = syncobj_create(fd, 0);
> +	syncobjs[3] = syncobj_create(fd, 0);
> +
> +	syncobj_timeline_signal(fd, syncobjs, points, 4);
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs,
> +						points, 3, 0, 0), 0);
> +	igt_assert_eq(syncobj_wait_err(fd, &syncobjs[3], 1, 0, 0), 0);
> +
> +	syncobj_destroy(fd, syncobjs[0]);
> +	syncobj_destroy(fd, syncobjs[1]);
> +	syncobj_destroy(fd, syncobjs[2]);
> +	syncobj_destroy(fd, syncobjs[3]);
> +}
> +
> +static const char *test_transfer_illegal_handle_desc =
> +	"Verifies that an invalid syncobj handle is rejected in"
> +	" drm_syncobj_transfer";
> +static void
> +test_transfer_illegal_handle(int fd)
> +{
> +	struct drm_syncobj_transfer args = {};
> +	uint32_t handle = 0;
> +	int ret;
> +
> +	args.src_handle = to_user_pointer(&handle);
> +	args.dst_handle = to_user_pointer(&handle);
> +	args.src_point = 1;
> +	args.dst_point = 0;
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
> +	igt_assert(ret == -1 && errno == ENOENT);
> +}
> +
> +static const char *test_transfer_bad_pad_desc =
> +	"Verifies that invalid drm_syncobj_transfer::pad field value is"
> +	" rejected";
> +static void
> +test_transfer_bad_pad(int fd)
> +{
> +	struct drm_syncobj_transfer arg = {};
> +	uint32_t handle = 0;
> +	int ret;
> +
> +	arg.pad = 0xdeadbeef;
> +	arg.src_handle = to_user_pointer(&handle);
> +	arg.dst_handle = to_user_pointer(&handle);
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &arg);
> +	igt_assert(ret == -1 && errno == EINVAL);
> +}
> +
> +#define WAIT_FOR_SUBMIT		(1 << 0)
> +#define WAIT_ALL		(1 << 1)
> +#define WAIT_AVAILABLE		(1 << 2)
> +#define WAIT_UNSUBMITTED	(1 << 3)
> +#define WAIT_SUBMITTED		(1 << 4)
> +#define WAIT_SIGNALED		(1 << 5)
> +#define WAIT_FLAGS_MAX		(1 << 6) - 1
> +
> +static uint32_t
> +flags_for_test_flags(uint32_t test_flags)
> +{
> +	uint32_t flags = 0;
> +
> +	if (test_flags & WAIT_FOR_SUBMIT)
> +		flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
> +
> +	if (test_flags & WAIT_AVAILABLE)
> +		flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE;
> +
> +	if (test_flags & WAIT_ALL)
> +		flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL;
> +
> +	return flags;
> +}
> +
> +static const char *test_signal_wait_desc =
> +	"Verifies wait behavior on a single timeline syncobj";
> +static void
> +test_single_wait(int fd, uint32_t test_flags, int expect)
> +{
> +	uint32_t syncobj = syncobj_create(fd, 0);
> +	uint32_t flags = flags_for_test_flags(test_flags);
> +	uint64_t point = 1;
> +	int timeline = -1;
> +
> +	if (test_flags & (WAIT_SUBMITTED | WAIT_SIGNALED))
> +		timeline = syncobj_attach_sw_sync(fd, syncobj, point);
> +
> +	if (test_flags & WAIT_SIGNALED)
> +		sw_sync_timeline_inc(timeline, 1);
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point, 1,
> +						0, flags), expect);
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point, 1,
> +						short_timeout(), flags), expect);
> +
> +	if (expect != -ETIME) {
> +		igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point, 1,
> +							UINT64_MAX, flags), expect);
> +	}
> +
> +	syncobj_destroy(fd, syncobj);
> +	if (timeline != -1)
> +		close(timeline);
> +}
> +
> +static const char *test_wait_delayed_signal_desc =
> +	"Verifies wait behavior on a timeline syncobj with a delayed signal"
> +	" from a different thread";
> +static void
> +test_wait_delayed_signal(int fd, uint32_t test_flags)
> +{
> +	uint32_t syncobj = syncobj_create(fd, 0);
> +	uint32_t flags = flags_for_test_flags(test_flags);
> +	uint64_t point = 1;
> +	int timeline = -1;
> +	timer_t timer;
> +
> +	if (test_flags & WAIT_FOR_SUBMIT) {
> +		timer = syncobj_trigger_delayed(fd, syncobj, point, SHORT_TIME_NSEC);
> +	} else {
> +		timeline = syncobj_attach_sw_sync(fd, syncobj, point);
> +		timer = set_timer(timeline_inc_func, NULL,
> +				  timeline, SHORT_TIME_NSEC);
> +	}
> +
> +	igt_assert(syncobj_timeline_wait(fd, &syncobj, &point, 1,
> +				gettime_ns() + SHORT_TIME_NSEC * 2,
> +				flags, NULL));
> +
> +	timer_delete(timer);
> +
> +	if (timeline != -1)
> +		close(timeline);
> +
> +	syncobj_destroy(fd, syncobj);
> +}
> +
> +static const char *test_reset_unsignaled_desc =
> +	"Verifies behavior of a reset operation on an unsignaled timeline"
> +	" syncobj";
> +static void
> +test_reset_unsignaled(int fd)
> +{
> +	uint32_t syncobj = syncobj_create(fd, 0);
> +	uint64_t point = 1;
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
> +						1, 0, 0), -EINVAL);
> +
> +	syncobj_reset(fd, &syncobj, 1);
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
> +						1, 0, 0), -EINVAL);
> +
> +	syncobj_destroy(fd, syncobj);
> +}
> +
> +static const char *test_reset_signaled_desc =
> +	"Verifies behavior of a reset operation on a signaled timeline syncobj";
> +static void
> +test_reset_signaled(int fd)
> +{
> +	uint32_t syncobj = syncobj_create(fd, 0);
> +	uint64_t point = 1;
> +
> +	syncobj_trigger(fd, syncobj, point);
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
> +						1, 0, 0), 0);
> +
> +	syncobj_reset(fd, &syncobj, 1);
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
> +						1, 0, 0), -EINVAL);
> +
> +	syncobj_destroy(fd, syncobj);
> +}
> +
> +static const char *test_reset_multiple_signaled_desc =
> +	"Verifies behavior of a reset operation on a list of signaled timeline"
> +	" syncobjs";
> +static void
> +test_reset_multiple_signaled(int fd)
> +{
> +	uint64_t points[3] = {1, 1, 1};
> +	uint32_t syncobjs[3];
> +	int i;
> +
> +	for (i = 0; i < 3; i++) {
> +		syncobjs[i] = syncobj_create(fd, 0);
> +		syncobj_trigger(fd, syncobjs[i], points[i]);
> +	}
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs, points, 3, 0, 0), 0);
> +
> +	syncobj_reset(fd, syncobjs, 3);
> +
> +	for (i = 0; i < 3; i++) {
> +		igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[i],
> +							&points[i], 1,
> +							0, 0), -EINVAL);
> +		syncobj_destroy(fd, syncobjs[i]);
> +	}
> +}
> +
> +static void
> +reset_and_trigger_func(union sigval sigval)
> +{
> +	struct fd_handle_pair *pair = sigval.sival_ptr;
> +	syncobj_reset(pair->fd, &pair->handle, 1);
> +	syncobj_trigger(pair->fd, pair->handle, pair->point);
> +}
> +
> +static const char *test_reset_during_wait_for_submit_desc =
> +	"Verifies behavior of a reset operation a timeline syncobj while wait"
> +	" operation is ongoing";
> +static void
> +test_reset_during_wait_for_submit(int fd)
> +{
> +	uint32_t syncobj = syncobj_create(fd, 0);
> +	uint32_t flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
> +	struct fd_handle_pair pair;
> +	uint64_t point = 1;
> +	timer_t timer;
> +
> +	pair.fd = fd;
> +	pair.handle = syncobj;
> +	timer = set_timer(reset_and_trigger_func, &pair, 0, SHORT_TIME_NSEC);
> +
> +	/* A reset should be a no-op even if we're in the middle of a wait */
> +	igt_assert(syncobj_timeline_wait(fd, &syncobj, &point, 1,
> +				gettime_ns() + SHORT_TIME_NSEC * 2,
> +				flags, NULL));
> +
> +	timer_delete(timer);
> +
> +	syncobj_destroy(fd, syncobj);
> +}
> +
> +static const char *test_signal_desc =
> +	"Verifies basic signaling of a timeline syncobj";
> +static void
> +test_signal(int fd)
> +{
> +	uint32_t syncobj = syncobj_create(fd, 0);
> +	uint32_t flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
> +	uint64_t point = 1;
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
> +						1, 0, 0), -EINVAL);
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
> +						1, 0, flags), -ETIME);
> +
> +	syncobj_timeline_signal(fd, &syncobj, &point, 1);
> +
> +	igt_assert(syncobj_timeline_wait(fd, &syncobj, &point, 1, 0, 0, NULL));
> +	igt_assert(syncobj_timeline_wait(fd, &syncobj, &point, 1, 0, flags, NULL));
> +
> +	syncobj_destroy(fd, syncobj);
> +}
> +
> +static const char *test_multi_wait_desc =
> +	"Verifies waiting on a list of timeline syncobjs";
> +static void
> +test_multi_wait(int fd, uint32_t test_flags, int expect)
> +{
> +	uint32_t tflag, flags;
> +	int i, fidx, timeline;
> +	uint64_t points[5] = {
> +		1 + rand() % 1000,
> +		0, /* non timeline syncobj */
> +		1 + rand() % 1000,
> +		1 + rand() % 1000,
> +		0, /* non timeline syncobj */
> +	};
> +	uint32_t syncobjs[ARRAY_SIZE(points)];
> +
> +	for (i = 0; i < ARRAY_SIZE(points); i++)
> +		syncobjs[i] = syncobj_create(fd, 0);
> +
> +	flags = flags_for_test_flags(test_flags);
> +	test_flags &= ~(WAIT_ALL | WAIT_FOR_SUBMIT | WAIT_AVAILABLE);
> +
> +	for (i = 0; i < ARRAY_SIZE(points); i++) {
> +		fidx = ffs(test_flags) - 1;
> +		tflag = (1 << fidx);
> +
> +		if (test_flags & ~tflag)
> +			test_flags &= ~tflag;
> +
> +		if (tflag & (WAIT_SUBMITTED | WAIT_SIGNALED)) {
> +			timeline = syncobj_attach_sw_sync(fd, syncobjs[i],
> +							  points[i]);
> +		}
> +		if (tflag & WAIT_SIGNALED)
> +			sw_sync_timeline_inc(timeline, 1);
> +	}
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs,
> +						points, ARRAY_SIZE(points),
> +						0, flags), expect);
> +
> +	igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs,
> +						points, ARRAY_SIZE(points),
> +						short_timeout(),
> +						flags), expect);
> +
> +	if (expect != -ETIME) {
> +		igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs,
> +							points, ARRAY_SIZE(points),
> +							UINT64_MAX,
> +							flags), expect);
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(points); i++)
> +		syncobj_destroy(fd, syncobjs[i]);
> +}
> +
> +struct wait_thread_data {
> +	int fd;
> +	struct drm_syncobj_timeline_wait wait;
> +};
> +
> +static void *
> +wait_thread_func(void *data)
> +{
> +	struct wait_thread_data *wait = data;
> +	igt_assert_eq(__syncobj_timeline_wait_ioctl(wait->fd, &wait->wait), 0);
> +	return NULL;
> +}
> +
> +static const char *test_wait_snapshot_desc =
> +	"Verifies waiting on a list of timeline syncobjs with different thread"
> +	" for wait/signal";
> +static void
> +test_wait_snapshot(int fd, uint32_t test_flags)
> +{
> +	struct wait_thread_data wait = {};
> +	uint32_t syncobjs[2];
> +	uint64_t points[2] = {1, 1};
> +	int timelines[3] = { -1, -1, -1 };
> +	pthread_t thread;
> +
> +	syncobjs[0] = syncobj_create(fd, 0);
> +	syncobjs[1] = syncobj_create(fd, 0);
> +
> +	if (!(test_flags & WAIT_FOR_SUBMIT)) {
> +		timelines[0] = syncobj_attach_sw_sync(fd, syncobjs[0], points[0]);
> +		timelines[1] = syncobj_attach_sw_sync(fd, syncobjs[1], points[1]);
> +	}
> +
> +	wait.fd = fd;
> +	wait.wait.handles = to_user_pointer(syncobjs);
> +	wait.wait.count_handles = 2;
> +	wait.wait.points = to_user_pointer(points);
> +	wait.wait.timeout_nsec = short_timeout();
> +	wait.wait.flags = flags_for_test_flags(test_flags);
> +
> +	igt_assert_eq(pthread_create(&thread, NULL, wait_thread_func, &wait), 0);
> +
> +	sleep_nsec(SHORT_TIME_NSEC / 5);
> +
> +	/* Try to fake the kernel out by triggering or partially triggering
> +	 * the first fence.
> +	 */
> +	if (test_flags & WAIT_ALL) {
> +		/* If it's WAIT_ALL, actually trigger it */
> +		if (timelines[0] == -1)
> +			syncobj_trigger(fd, syncobjs[0], points[0]);
> +		else
> +			sw_sync_timeline_inc(timelines[0], 1);
> +	} else if (test_flags & WAIT_FOR_SUBMIT) {
> +		timelines[0] = syncobj_attach_sw_sync(fd, syncobjs[0], points[0]);
> +	}
> +
> +	sleep_nsec(SHORT_TIME_NSEC / 5);
> +
> +	/* Then reset it */
> +	syncobj_reset(fd, &syncobjs[0], 1);
> +
> +	sleep_nsec(SHORT_TIME_NSEC / 5);
> +
> +	/* Then "submit" it in a way that will never trigger.  This way, if
> +	 * the kernel picks up on the new fence (it shouldn't), we'll get a
> +	 * timeout.
> +	 */
> +	timelines[2] = syncobj_attach_sw_sync(fd, syncobjs[0], points[0]);
> +
> +	sleep_nsec(SHORT_TIME_NSEC / 5);
> +
> +	/* Now trigger the second fence to complete the wait */
> +
> +	if (timelines[1] == -1)
> +		syncobj_trigger(fd, syncobjs[1], points[1]);
> +	else
> +		sw_sync_timeline_inc(timelines[1], 1);
> +
> +	pthread_join(thread, NULL);
> +
> +	if (!(test_flags & WAIT_ALL))
> +		igt_assert_eq(wait.wait.first_signaled, 1);
> +
> +	close(timelines[0]);
> +	close(timelines[1]);
> +	close(timelines[2]);
> +	syncobj_destroy(fd, syncobjs[0]);
> +	syncobj_destroy(fd, syncobjs[1]);
> +}
> +
> +/* The numbers 0-7, each repeated 5x and shuffled. */
> +static const unsigned shuffled_0_7_x4[] = {
> +	2, 0, 6, 1, 1, 4, 5, 2, 0, 7, 1, 7, 6, 3, 4, 5,
> +	0, 2, 7, 3, 5, 4, 0, 6, 7, 3, 2, 5, 6, 1, 4, 3,
> +};
> +
> +enum syncobj_stage {
> +	STAGE_UNSUBMITTED,
> +	STAGE_SUBMITTED,
> +	STAGE_SIGNALED,
> +	STAGE_RESET,
> +	STAGE_RESUBMITTED,
> +};
> +
> +static const char *test_wait_complex_desc =
> +	"Verifies timeline syncobj at different signal/operations stages &"
> +	" between different threads.";
> +static void
> +test_wait_complex(int fd, uint32_t test_flags)
> +{
> +	struct wait_thread_data wait = {};
> +	uint32_t syncobjs[8];
> +	uint64_t points[8] = {1, 1, 1, 1, 1, 1, 1, 1};
> +	enum syncobj_stage stage[8];
> +	int i, j, timelines[8];
> +	uint32_t first_signaled = -1, num_signaled = 0;
> +	pthread_t thread;
> +
> +	for (i = 0; i < 8; i++) {
> +		stage[i] = STAGE_UNSUBMITTED;
> +		syncobjs[i] = syncobj_create(fd, 0);
> +	}
> +
> +	if (test_flags & WAIT_FOR_SUBMIT) {
> +		for (i = 0; i < 8; i++)
> +			timelines[i] = -1;
> +	} else {
> +		for (i = 0; i < 8; i++)
> +			timelines[i] = syncobj_attach_sw_sync(fd, syncobjs[i],
> +							      points[i]);
> +	}
> +
> +	wait.fd = fd;
> +	wait.wait.handles = to_user_pointer(syncobjs);
> +	wait.wait.count_handles = 2;
> +	wait.wait.points = to_user_pointer(points);
> +	wait.wait.timeout_nsec = gettime_ns() + NSECS_PER_SEC;
> +	wait.wait.flags = flags_for_test_flags(test_flags);
> +
> +	igt_assert_eq(pthread_create(&thread, NULL, wait_thread_func, &wait), 0);
> +
> +	sleep_nsec(NSECS_PER_SEC / 50);
> +
> +	num_signaled = 0;
> +	for (j = 0; j < ARRAY_SIZE(shuffled_0_7_x4); j++) {
> +		i = shuffled_0_7_x4[j];
> +		igt_assert_lt(i, ARRAY_SIZE(syncobjs));
> +
> +		switch (stage[i]++) {
> +		case STAGE_UNSUBMITTED:
> +			/* We need to submit attach a fence */
> +			if (!(test_flags & WAIT_FOR_SUBMIT)) {
> +				/* We had to attach one up-front */
> +				igt_assert_neq(timelines[i], -1);
> +				break;
> +			}
> +			timelines[i] = syncobj_attach_sw_sync(fd, syncobjs[i],
> +							      points[i]);
> +			break;
> +
> +		case STAGE_SUBMITTED:
> +			/* We have a fence, trigger it */
> +			igt_assert_neq(timelines[i], -1);
> +			sw_sync_timeline_inc(timelines[i], 1);
> +			close(timelines[i]);
> +			timelines[i] = -1;
> +			if (num_signaled == 0)
> +				first_signaled = i;
> +			num_signaled++;
> +			break;
> +
> +		case STAGE_SIGNALED:
> +			/* We're already signaled, reset */
> +			syncobj_reset(fd, &syncobjs[i], 1);
> +			break;
> +
> +		case STAGE_RESET:
> +			/* We're reset, submit and don't signal */
> +			timelines[i] = syncobj_attach_sw_sync(fd, syncobjs[i],
> +							      points[i]);
> +			break;
> +
> +		case STAGE_RESUBMITTED:
> +			igt_assert(!"Should not reach this stage");
> +			break;
> +		}
> +
> +		if (test_flags & WAIT_ALL) {
> +			if (num_signaled == ARRAY_SIZE(syncobjs))
> +				break;
> +		} else {
> +			if (num_signaled > 0)
> +				break;
> +		}
> +
> +		sleep_nsec(NSECS_PER_SEC / 100);
> +	}
> +
> +	pthread_join(thread, NULL);
> +
> +	if (test_flags & WAIT_ALL) {
> +		igt_assert_eq(num_signaled, ARRAY_SIZE(syncobjs));
> +	} else {
> +		igt_assert_eq(num_signaled, 1);
> +		igt_assert_eq(wait.wait.first_signaled, first_signaled);
> +	}
> +
> +	for (i = 0; i < 8; i++) {
> +		close(timelines[i]);
> +		syncobj_destroy(fd, syncobjs[i]);
> +	}
> +}
> +
> +static const char *test_wait_interrupted_desc =
> +	"Verifies timeline syncobj waits interaction with signals.";
> +static void
> +test_wait_interrupted(int fd, uint32_t test_flags)
> +{
> +	struct drm_syncobj_timeline_wait wait = {};
> +	uint32_t syncobj = syncobj_create(fd, 0);
> +	uint64_t point = 1;
> +	int timeline;
> +
> +	wait.handles = to_user_pointer(&syncobj);
> +	wait.points = to_user_pointer(&point);
> +	wait.count_handles = 1;
> +	wait.flags = flags_for_test_flags(test_flags);
> +
> +	if (test_flags & WAIT_FOR_SUBMIT) {
> +		wait.timeout_nsec = short_timeout();
> +		igt_while_interruptible(true)
> +			igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -ETIME);
> +	}
> +
> +	timeline = syncobj_attach_sw_sync(fd, syncobj, point);
> +
> +	wait.timeout_nsec = short_timeout();
> +	igt_while_interruptible(true)
> +		igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -ETIME);
> +
> +	syncobj_destroy(fd, syncobj);
> +	close(timeline);
> +}
> +
> +static bool
> +has_syncobj_timeline_wait(int fd)
> +{
> +	struct drm_syncobj_timeline_wait wait = {};
> +	uint32_t handle = 0;
> +	uint64_t value;
> +	int ret;
> +
> +	if (drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &value))
> +		return false;
> +	if (!value)
> +		return false;
> +
> +	/* Try waiting for zero sync objects should fail with EINVAL */
> +	wait.count_handles = 1;
> +	wait.handles = to_user_pointer(&handle);
> +	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &wait);
> +	return ret == -1 && errno == ENOENT;
> +}
> +
> +igt_main
> +{
> +	int fd = -1;
> +
> +	igt_fixture {
> +		fd = drm_open_driver(DRIVER_ANY);
> +		igt_require(has_syncobj_timeline_wait(fd));
> +		igt_require_sw_sync();
> +	}
> +
> +	igt_describe(test_wait_bad_flags_desc);
> +	igt_subtest("invalid-wait-bad-flags")
> +		test_wait_bad_flags(fd);
> +
> +	igt_describe(test_wait_zero_handles_desc);
> +	igt_subtest("invalid-wait-zero-handles")
> +		test_wait_zero_handles(fd);
> +
> +	igt_describe(test_wait_illegal_handle_desc);
> +	igt_subtest("invalid-wait-illegal-handle")
> +		test_wait_illegal_handle(fd);
> +
> +	igt_describe(test_query_zero_handles_desc);
> +	igt_subtest("invalid-query-zero-handles")
> +		test_query_zero_handles(fd);
> +
> +	igt_describe(test_query_illegal_handle_desc);
> +	igt_subtest("invalid-query-illegal-handle")
> +		test_query_illegal_handle(fd);
> +
> +	igt_describe(test_query_one_illegal_handle_desc);
> +	igt_subtest("invalid-query-one-illegal-handle")
> +		test_query_one_illegal_handle(fd);
> +
> +	igt_describe(test_query_bad_pad_desc);
> +	igt_subtest("invalid-query-bad-pad")
> +		test_query_bad_pad(fd);
> +
> +	igt_describe(test_signal_zero_handles_desc);
> +	igt_subtest("invalid-signal-zero-handles")
> +		test_signal_zero_handles(fd);
> +
> +	igt_describe(test_signal_illegal_handle_desc);
> +	igt_subtest("invalid-signal-illegal-handle")
> +		test_signal_illegal_handle(fd);
> +
> +	igt_subtest("invalid-signal-illegal-point")
> +		test_signal_illegal_point(fd);
> +
> +	igt_describe(test_signal_one_illegal_handle_desc);
> +	igt_subtest("invalid-signal-one-illegal-handle")
> +		test_signal_one_illegal_handle(fd);
> +
> +	igt_describe(test_signal_bad_pad_desc);
> +	igt_subtest("invalid-signal-bad-pad")
> +		test_signal_bad_pad(fd);
> +
> +	igt_describe(test_signal_array_desc);
> +	igt_subtest("signal-array")
> +		test_signal_array(fd);
> +
> +	igt_describe(test_transfer_illegal_handle_desc);
> +	igt_subtest("invalid-transfer-illegal-handle")
> +		test_transfer_illegal_handle(fd);
> +
> +	igt_describe(test_transfer_bad_pad_desc);
> +	igt_subtest("invalid-transfer-bad-pad")
> +		test_transfer_bad_pad(fd);
> +
> +	for (unsigned flags = 0; flags < WAIT_FLAGS_MAX; flags++) {
> +		int err;
> +
> +		/* Only one wait mode for single-wait tests */
> +		if (__builtin_popcount(flags & (WAIT_UNSUBMITTED |
> +						WAIT_SUBMITTED |
> +						WAIT_SIGNALED)) != 1)
> +			continue;
> +
> +		if ((flags & WAIT_UNSUBMITTED) && !(flags & WAIT_FOR_SUBMIT))
> +			err = -EINVAL;
> +		else if (!(flags & WAIT_SIGNALED) && !((flags & WAIT_SUBMITTED) && (flags & WAIT_AVAILABLE)))
> +			err = -ETIME;
> +		else
> +			err = 0;
> +
> +		igt_describe(test_signal_wait_desc);
> +		igt_subtest_f("%ssingle-wait%s%s%s%s%s%s",
> +			      err == -EINVAL ? "invalid-" : err == -ETIME ? "etime-" : "",
> +			      (flags & WAIT_ALL) ? "-all" : "",
> +			      (flags & WAIT_FOR_SUBMIT) ? "-for-submit" : "",
> +			      (flags & WAIT_AVAILABLE) ? "-available" : "",
> +			      (flags & WAIT_UNSUBMITTED) ? "-unsubmitted" : "",
> +			      (flags & WAIT_SUBMITTED) ? "-submitted" : "",
> +			      (flags & WAIT_SIGNALED) ? "-signaled" : "")
> +			test_single_wait(fd, flags, err);
> +	}
> +
> +	igt_describe(test_wait_delayed_signal_desc);
> +	igt_subtest("wait-delayed-signal")
> +		test_wait_delayed_signal(fd, 0);
> +
> +	igt_describe(test_wait_delayed_signal_desc);
> +	igt_subtest("wait-for-submit-delayed-submit")
> +		test_wait_delayed_signal(fd, WAIT_FOR_SUBMIT);
> +
> +	igt_describe(test_wait_delayed_signal_desc);
> +	igt_subtest("wait-all-delayed-signal")
> +		test_wait_delayed_signal(fd, WAIT_ALL);
> +
> +	igt_describe(test_wait_delayed_signal_desc);
> +	igt_subtest("wait-all-for-submit-delayed-submit")
> +		test_wait_delayed_signal(fd, WAIT_ALL | WAIT_FOR_SUBMIT);
> +
> +	igt_describe(test_reset_unsignaled_desc);
> +	igt_subtest("reset-unsignaled")
> +		test_reset_unsignaled(fd);
> +
> +	igt_describe(test_reset_signaled_desc);
> +	igt_subtest("reset-signaled")
> +		test_reset_signaled(fd);
> +
> +	igt_describe(test_reset_multiple_signaled_desc);
> +	igt_subtest("reset-multiple-signaled")
> +		test_reset_multiple_signaled(fd);
> +
> +	igt_describe(test_reset_during_wait_for_submit_desc);
> +	igt_subtest("reset-during-wait-for-submit")
> +		test_reset_during_wait_for_submit(fd);
> +
> +	igt_describe(test_signal_desc);
> +	igt_subtest("signal")
> +		test_signal(fd);
> +
> +	for (unsigned flags = 0; flags < WAIT_FLAGS_MAX; flags++) {
> +		int err;
> +
> +		/* At least one wait mode for multi-wait tests */
> +		if (!(flags & (WAIT_UNSUBMITTED |
> +			       WAIT_SUBMITTED |
> +			       WAIT_SIGNALED)))
> +			continue;
> +
> +		err = 0;
> +		if ((flags & WAIT_UNSUBMITTED) && !(flags & WAIT_FOR_SUBMIT)) {
> +			err = -EINVAL;
> +		} else if (flags & WAIT_ALL) {
> +			if (flags & (WAIT_UNSUBMITTED | WAIT_SUBMITTED))
> +				err = -ETIME;
> +			if (!(flags & WAIT_UNSUBMITTED) && (flags & WAIT_SUBMITTED) && (flags & WAIT_AVAILABLE))
> +				err = 0;
> +		} else {
> +			if (!(flags & WAIT_SIGNALED) && !((flags & WAIT_SUBMITTED) && (flags & WAIT_AVAILABLE)))
> +				err = -ETIME;
> +		}
> +
> +		igt_describe(test_multi_wait_desc);
> +		igt_subtest_f("%smulti-wait%s%s%s%s%s%s",
> +			      err == -EINVAL ? "invalid-" : err == -ETIME ? "etime-" : "",
> +			      (flags & WAIT_ALL) ? "-all" : "",
> +			      (flags & WAIT_FOR_SUBMIT) ? "-for-submit" : "",
> +			      (flags & WAIT_AVAILABLE) ? "-available" : "",
> +			      (flags & WAIT_UNSUBMITTED) ? "-unsubmitted" : "",
> +			      (flags & WAIT_SUBMITTED) ? "-submitted" : "",
> +			      (flags & WAIT_SIGNALED) ? "-signaled" : "")
> +			test_multi_wait(fd, flags, err);
> +	}
> +
> +	igt_describe(test_wait_snapshot_desc);
> +	igt_subtest("wait-any-snapshot")
> +		test_wait_snapshot(fd, 0);
> +
> +	igt_describe(test_wait_snapshot_desc);
> +	igt_subtest("wait-all-snapshot")
> +		test_wait_snapshot(fd, WAIT_ALL);
> +
> +	igt_describe(test_wait_snapshot_desc);
> +	igt_subtest("wait-for-submit-snapshot")
> +		test_wait_snapshot(fd, WAIT_FOR_SUBMIT);
> +
> +	igt_describe(test_wait_snapshot_desc);
> +	igt_subtest("wait-all-for-submit-snapshot")
> +		test_wait_snapshot(fd, WAIT_ALL | WAIT_FOR_SUBMIT);
> +
> +	igt_describe(test_wait_complex_desc);
> +	igt_subtest("wait-any-complex")
> +		test_wait_complex(fd, 0);
> +
> +	igt_describe(test_wait_complex_desc);
> +	igt_subtest("wait-all-complex")
> +		test_wait_complex(fd, WAIT_ALL);
> +
> +	igt_describe(test_wait_complex_desc);
> +	igt_subtest("wait-for-submit-complex")
> +		test_wait_complex(fd, WAIT_FOR_SUBMIT);
> +
> +	igt_describe(test_wait_complex_desc);
> +	igt_subtest("wait-all-for-submit-complex")
> +		test_wait_complex(fd, WAIT_ALL | WAIT_FOR_SUBMIT);
> +
> +	igt_describe(test_wait_interrupted_desc);
> +	igt_subtest("wait-any-interrupted")
> +		test_wait_interrupted(fd, 0);
> +
> +	igt_describe(test_wait_interrupted_desc);
> +	igt_subtest("wait-all-interrupted")
> +		test_wait_interrupted(fd, WAIT_ALL);
> +}
> -- 
> 2.24.0
> 

> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [igt-dev] ✓ Fi.CI.IGT: success for tests: Add timeline syncobj testing
  2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
                   ` (11 preceding siblings ...)
       [not found] ` <20191120212143.364333-4-lionel.g.landwerlin@intel.com>
@ 2019-11-21 22:16 ` Patchwork
  12 siblings, 0 replies; 24+ messages in thread
From: Patchwork @ 2019-11-21 22:16 UTC (permalink / raw)
  To: Lionel Landwerlin; +Cc: igt-dev

== Series Details ==

Series: tests: Add timeline syncobj testing
URL   : https://patchwork.freedesktop.org/series/69782/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_7393_full -> IGTPW_3738_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_3738_full:

### IGT changes ###

#### Possible regressions ####

  * {igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-submitted-signaled} (NEW):
    - shard-iclb:         NOTRUN -> [SKIP][1] +120 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-iclb6/igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-submitted-signaled.html

  * {igt@syncobj_timeline@wait-all-complex} (NEW):
    - shard-tglb:         NOTRUN -> [SKIP][2] +78 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-tglb9/igt@syncobj_timeline@wait-all-complex.html

  
New tests
---------

  New tests have been introduced between CI_DRM_7393_full and IGTPW_3738_full:

### New IGT tests (121) ###

  * igt@syncobj_timeline@32bits-limit:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@device-signal-unordered:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@device-submit-unordered:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-for-submit-available-unsubmitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-for-submit-available-unsubmitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-for-submit-available-unsubmitted-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-for-submit-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-for-submit-submitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-for-submit-unsubmitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-for-submit-unsubmitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-for-submit-unsubmitted-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-for-submit-unsubmitted-submitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-all-submitted-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-for-submit-available-unsubmitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-for-submit-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-for-submit-unsubmitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-for-submit-unsubmitted-submitted:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-multi-wait-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-single-wait-all-for-submit-available-unsubmitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-single-wait-all-for-submit-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-single-wait-all-for-submit-unsubmitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-single-wait-all-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-single-wait-for-submit-available-unsubmitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-single-wait-for-submit-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-single-wait-for-submit-unsubmitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@etime-single-wait-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@host-signal-ordered:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@host-signal-points:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-all-available-unsubmitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-all-available-unsubmitted-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-all-available-unsubmitted-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-all-available-unsubmitted-submitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-signaled:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-submitted-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted-submitted-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-unsubmitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-unsubmitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-unsubmitted-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-multi-wait-unsubmitted-submitted-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-query-bad-pad:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-query-illegal-handle:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-query-one-illegal-handle:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-query-zero-handles:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-signal-bad-pad:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-signal-illegal-handle:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-signal-illegal-point:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-signal-one-illegal-handle:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-signal-zero-handles:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-single-wait-all-available-unsubmitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-single-wait-all-unsubmitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-single-wait-available-unsubmitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-single-wait-unsubmitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-transfer-bad-pad:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-transfer-illegal-handle:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-transfer-non-existent-point:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-wait-bad-flags:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-wait-illegal-handle:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@invalid-wait-zero-handles:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-all-available-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-all-available-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-all-available-submitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-all-for-submit-available-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-all-for-submit-available-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-all-for-submit-available-submitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-all-for-submit-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-all-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-available-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-available-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-available-submitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-available-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-available-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-available-submitted-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-available-unsubmitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-available-unsubmitted-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-available-unsubmitted-submitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-submitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-unsubmitted-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-for-submit-unsubmitted-submitted-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@multi-wait-submitted-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@reset-during-wait-for-submit:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@reset-multiple-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@reset-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@reset-unsignaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@signal:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@signal-array:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@signal-point-0:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-all-available-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-all-available-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-all-for-submit-available-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-all-for-submit-available-submitted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-all-for-submit-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-all-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-available-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-available-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-for-submit-available-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-for-submit-available-submitted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-for-submit-signaled:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@single-wait-signaled:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@transfer-timeline-point:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-all-complex:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-all-delayed-signal:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-all-for-submit-complex:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-all-for-submit-delayed-submit:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-all-for-submit-snapshot:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-all-interrupted:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-all-snapshot:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-any-complex:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-any-interrupted:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-any-snapshot:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-delayed-signal:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-for-submit-complex:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-for-submit-delayed-submit:
    - Statuses : 6 skip(s)
    - Exec time: [0.0] s

  * igt@syncobj_timeline@wait-for-submit-snapshot:
    - Statuses : 7 skip(s)
    - Exec time: [0.0] s

  

Known issues
------------

  Here are the changes found in IGTPW_3738_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_busy@busy-vcs1:
    - shard-iclb:         [PASS][3] -> [SKIP][4] ([fdo#112080]) +15 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-iclb1/igt@gem_busy@busy-vcs1.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-iclb8/igt@gem_busy@busy-vcs1.html

  * igt@gem_ctx_isolation@vcs1-dirty-create:
    - shard-iclb:         [PASS][5] -> [SKIP][6] ([fdo#109276] / [fdo#112080]) +3 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-iclb4/igt@gem_ctx_isolation@vcs1-dirty-create.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-iclb3/igt@gem_ctx_isolation@vcs1-dirty-create.html

  * igt@gem_ctx_shared@exec-single-timeline-bsd:
    - shard-iclb:         [PASS][7] -> [SKIP][8] ([fdo#110841])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-iclb8/igt@gem_ctx_shared@exec-single-timeline-bsd.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-iclb2/igt@gem_ctx_shared@exec-single-timeline-bsd.html

  * igt@gem_exec_balancer@smoke:
    - shard-iclb:         [PASS][9] -> [SKIP][10] ([fdo#110854])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-iclb1/igt@gem_exec_balancer@smoke.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-iclb6/igt@gem_exec_balancer@smoke.html

  * igt@gem_exec_schedule@in-order-bsd:
    - shard-iclb:         [PASS][11] -> [SKIP][12] ([fdo#112146]) +5 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-iclb6/igt@gem_exec_schedule@in-order-bsd.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-iclb1/igt@gem_exec_schedule@in-order-bsd.html

  * igt@gem_exec_schedule@preempt-queue-bsd2:
    - shard-tglb:         [PASS][13] -> [INCOMPLETE][14] ([fdo#111606] / [fdo#111677])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-tglb4/igt@gem_exec_schedule@preempt-queue-bsd2.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-tglb6/igt@gem_exec_schedule@preempt-queue-bsd2.html

  * igt@gem_exec_suspend@basic-s0:
    - shard-tglb:         [PASS][15] -> [INCOMPLETE][16] ([fdo#111832])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-tglb6/igt@gem_exec_suspend@basic-s0.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-tglb4/igt@gem_exec_suspend@basic-s0.html

  * igt@gem_userptr_blits@dmabuf-sync:
    - shard-snb:          [PASS][17] -> [DMESG-WARN][18] ([fdo#111870])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-snb4/igt@gem_userptr_blits@dmabuf-sync.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-snb2/igt@gem_userptr_blits@dmabuf-sync.html

  * igt@i915_selftest@live_perf:
    - shard-hsw:          [PASS][19] -> [INCOMPLETE][20] ([fdo#103540]) +1 similar issue
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-hsw1/igt@i915_selftest@live_perf.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-hsw1/igt@i915_selftest@live_perf.html

  * igt@kms_cursor_legacy@cursor-vs-flip-varying-size:
    - shard-hsw:          [PASS][21] -> [FAIL][22] ([fdo#103355])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-hsw8/igt@kms_cursor_legacy@cursor-vs-flip-varying-size.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-hsw6/igt@kms_cursor_legacy@cursor-vs-flip-varying-size.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-apl:          [PASS][23] -> [DMESG-WARN][24] ([fdo#108566]) +1 similar issue
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-apl1/igt@kms_flip@flip-vs-suspend-interruptible.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-apl6/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-render:
    - shard-iclb:         [PASS][25] -> [FAIL][26] ([fdo#103167]) +2 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-iclb8/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-render.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-iclb8/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-pwrite:
    - shard-tglb:         [PASS][27] -> [FAIL][28] ([fdo#103167]) +4 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7393/shard-tglb6/igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-pwrite.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/shard-tglb2/igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-pwrite.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes:
    - shard-kbl:          [PASS][29] -> [DMESG-W

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_3738/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 03/10] igt: add timeline test cases
  2019-11-21 14:07   ` [igt-dev] [PATCH i-g-t 03/10] igt: add timeline test cases Petri Latvala
@ 2019-11-22 13:03     ` Lionel Landwerlin
  0 siblings, 0 replies; 24+ messages in thread
From: Lionel Landwerlin @ 2019-11-22 13:03 UTC (permalink / raw)
  To: Petri Latvala; +Cc: igt-dev, Chunming Zhou

On 21/11/2019 16:07, Petri Latvala wrote:
> On Wed, Nov 20, 2019 at 11:21:36PM +0200, Lionel Landwerlin wrote:
>> From: Chunming Zhou <david1.zhou@amd.com>
>>
>> v2: adapt to new transfer ioctl
>>
>> v3: Drop useless uint64_t casts (Lionel)
>>      Fix timeline query prototypes (Lionel)
>>      Test multi wait with timeline & binary syncobjs (Lionel)
>>
>> v4: Switch from drmIoctl to igt_ioctl in tests/*.c (Chris)
>>      Clear out errno in helper functions (Chris)
>>
>> v5: Fix lib comments on transfer helpers (Lionel)
>>
>> v6: Add igt_describe() (Lionel)
>>
>> Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
>> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>> ---
>>   lib/igt_syncobj.c        |  237 ++++++++
>>   lib/igt_syncobj.h        |   19 +
>>   tests/meson.build        |    1 +
> Corresponding autotools change missing.
>
>
And I just forgot to address this...

For v3...

-Lionel

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2019-11-22 13:03 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-20 21:21 [igt-dev] [PATCH i-g-t 00/10] tests: Add timeline syncobj testing Lionel Landwerlin
2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 01/10] lib/syncobj: drop local declarations Lionel Landwerlin
2019-11-20 21:49   ` Chris Wilson
2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 02/10] drm-uapi: Update drm headers to 17cc51390c141662748dbbc2fe98f3ed10f2e13e Lionel Landwerlin
2019-11-20 21:50   ` Chris Wilson
2019-11-21 11:10     ` Lionel Landwerlin
2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 05/10] tests/i915/exec_fence: switch to internal headers Lionel Landwerlin
2019-11-20 21:51   ` Chris Wilson
2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 06/10] tests/i915/exec_fence: reuse syncobj helpers Lionel Landwerlin
2019-11-20 21:52   ` Chris Wilson
2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 07/10] include: bump drm headers for i915 timeline semaphores Lionel Landwerlin
2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 08/10] tests/i915/exec_fence: add timeline fence tests Lionel Landwerlin
2019-11-20 21:40   ` Chris Wilson
2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 09/10] lib/i915: add mmio base for engines Lionel Landwerlin
2019-11-20 21:42   ` Chris Wilson
2019-11-21 13:15     ` Lionel Landwerlin
2019-11-20 21:21 ` [igt-dev] [PATCH i-g-t 10/10] tests/i915/gem_exec_fence: add engine chaining tests Lionel Landwerlin
2019-11-20 22:02   ` Chris Wilson
     [not found] ` <20191120212143.364333-5-lionel.g.landwerlin@intel.com>
2019-11-20 21:33   ` [igt-dev] [PATCH i-g-t 04/10] tests/syncobj_timeline: add more timeline tests Chris Wilson
2019-11-20 23:02 ` [igt-dev] ✗ GitLab.Pipeline: warning for tests: Add timeline syncobj testing Patchwork
2019-11-20 23:42 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
     [not found] ` <20191120212143.364333-4-lionel.g.landwerlin@intel.com>
2019-11-21 14:07   ` [igt-dev] [PATCH i-g-t 03/10] igt: add timeline test cases Petri Latvala
2019-11-22 13:03     ` Lionel Landwerlin
2019-11-21 22:16 ` [igt-dev] ✓ Fi.CI.IGT: success for tests: Add timeline syncobj testing Patchwork

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.