From 241e7f379aeaa9b22a32277e77ad4011c8717a57 Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Tue, 18 Jul 2023 12:23:16 -0700
Subject: [PATCH] Make use of DRM_IOCTL_SYNCOBJ_IMPORT_SYNC_FILE

This new ioctl allows importing a sync file to a particular timeline
point on a syncobj. It eliminates the need to use a temporary binary
syncobj along with DRM_IOCTL_SYNCOBJ_TRANSFER.

Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
---
 include/drm-uapi/drm.h      | 11 ++++++++++
 lib/igt_syncobj.c           | 14 +++++++++----
 lib/igt_syncobj.h           |  3 ++-
 tests/i915/gem_exec_fence.c |  2 +-
 tests/syncobj_timeline.c    | 41 ++++++-------------------------------
 tests/syncobj_wait.c        |  2 +-
 tests/xe/xe_dma_buf_sync.c  |  2 +-
 7 files changed, 32 insertions(+), 43 deletions(-)

diff --git a/include/drm-uapi/drm.h b/include/drm-uapi/drm.h
index 5e54c3aa4..419b8e895 100644
--- a/include/drm-uapi/drm.h
+++ b/include/drm-uapi/drm.h
@@ -878,6 +878,12 @@ struct drm_syncobj_transfer {
 	__u32 pad;
 };
 
+struct drm_syncobj_sync_file {
+	__u32 handle;
+	__u32 fd;
+	__u64 point;
+};
+
 #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 */
@@ -1090,6 +1096,11 @@ extern "C" {
 #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_IMPORT_SYNC_FILE	DRM_IOWR(0xCE, struct drm_syncobj_sync_file)
+#define DRM_IOCTL_SYNCOBJ_EXPORT_SYNC_FILE	DRM_IOWR(0xCF, struct drm_syncobj_sync_file)
+
+
+
 #define DRM_IOCTL_MODE_GETFB2		DRM_IOWR(0xCE, struct drm_mode_fb_cmd2)
 
 /*
diff --git a/lib/igt_syncobj.c b/lib/igt_syncobj.c
index a24ed10b7..1f9307e70 100644
--- a/lib/igt_syncobj.c
+++ b/lib/igt_syncobj.c
@@ -168,17 +168,23 @@ syncobj_fd_to_handle(int fd, int syncobj_fd, uint32_t flags)
  * @fd: The DRM file descriptor
  * @handle: Handle to the syncobt to import file into
  * @sync_file: The sync_file fd to import state from.
+ * @point: The timeline point to import into. Must be 0
+ *         for binary syncobjs.
  *
  * Import a sync_file fd into a syncobj handle.
  */
 void
-syncobj_import_sync_file(int fd, uint32_t handle, int sync_file)
+syncobj_import_sync_file(int fd, uint32_t handle,
+	                     int sync_file, uint64_t point)
 {
-	struct drm_syncobj_handle args = { 0 };
+	struct drm_syncobj_sync_file args = { 0 };
+	int ret;
+
 	args.handle = handle;
 	args.fd = sync_file;
-	args.flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE;
-	igt_assert_eq(__syncobj_fd_to_handle(fd, &args), 0);
+	args.point = point;
+	ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_IMPORT_SYNC_FILE, &args);
+	igt_assert_eq(ret, 0);
 }
 
 int
diff --git a/lib/igt_syncobj.h b/lib/igt_syncobj.h
index e6725671d..df36f54bd 100644
--- a/lib/igt_syncobj.h
+++ b/lib/igt_syncobj.h
@@ -34,7 +34,8 @@ int __syncobj_handle_to_fd(int fd, struct drm_syncobj_handle *args);
 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);
+void syncobj_import_sync_file(int fd, uint32_t handle,
+			      int sync_file, uint64_t point);
 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);
diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 4bf29a3e4..0853107d7 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -1828,7 +1828,7 @@ static void test_syncobj_import(int fd)
 
 	fence = execbuf.rsvd2 >> 32;
 	igt_assert(fence_busy(fence));
-	syncobj_import_sync_file(fd, sync, fence);
+	syncobj_import_sync_file(fd, sync, fence, 0);
 	close(fence);
 
 	igt_assert(gem_bo_busy(fd, obj.handle));
diff --git a/tests/syncobj_timeline.c b/tests/syncobj_timeline.c
index b4e1d093a..2ea387572 100644
--- a/tests/syncobj_timeline.c
+++ b/tests/syncobj_timeline.c
@@ -467,16 +467,7 @@ syncobj_attach_sw_sync(int fd, uint32_t handle, uint64_t point)
 	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);
-	}
-
+	syncobj_import_sync_file(fd, handle, fence, point);
 	close(fence);
 
 	return timeline;
@@ -847,12 +838,8 @@ test_transfer_point(int fd)
 
 	{
 		int sw_fence = sw_sync_timeline_create_fence(timeline, 1);
-		uint32_t tmp_syncobj = syncobj_create(fd, 0);
-
-		syncobj_import_sync_file(fd, tmp_syncobj, sw_fence);
-		syncobj_binary_to_timeline(fd, handle, 1, tmp_syncobj);
+		syncobj_import_sync_file(fd, handle, sw_fence, 1);
 		close(sw_fence);
-		syncobj_destroy(fd, tmp_syncobj);
 	}
 
 	syncobj_timeline_query(fd, &handle, &value, 1);
@@ -1458,11 +1445,7 @@ test_device_signal_unordered(int fd)
 	}
 
 	for (i = 0; i < ARRAY_SIZE(fences); i++) {
-		uint32_t tmp_syncobj = syncobj_create(fd, 0);
-
-		syncobj_import_sync_file(fd, tmp_syncobj, fences[i]);
-		syncobj_binary_to_timeline(fd, syncobj, i + 1, tmp_syncobj);
-		syncobj_destroy(fd, tmp_syncobj);
+		syncobj_import_sync_file(fd, syncobj, fences[i], i + 1);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(fences); i++) {
@@ -1519,12 +1502,8 @@ test_device_submit_unordered(int fd)
 
 	for (i = 0; i < ARRAY_SIZE(points); i++) {
 		int fence = sw_sync_timeline_create_fence(timeline, i + 1);
-		uint32_t tmp_syncobj = syncobj_create(fd, 0);
-
-		syncobj_import_sync_file(fd, tmp_syncobj, fence);
-		syncobj_binary_to_timeline(fd, syncobj, points[i], tmp_syncobj);
+		syncobj_import_sync_file(fd, syncobj, fence, points[i]);
 		close(fence);
-		syncobj_destroy(fd, tmp_syncobj);
 	}
 
 	/*
@@ -1561,11 +1540,7 @@ test_host_signal_ordered(int fd)
 
 	for (i = 0; i < 5; i++) {
 		int fence = sw_sync_timeline_create_fence(timeline, i + 1);
-		uint32_t tmp_syncobj = syncobj_create(fd, 0);
-
-		syncobj_import_sync_file(fd, tmp_syncobj, fence);
-		syncobj_binary_to_timeline(fd, syncobj, i + 1, tmp_syncobj);
-		syncobj_destroy(fd, tmp_syncobj);
+		syncobj_import_sync_file(fd, syncobj, fence, i + 1);
 		close(fence);
 	}
 
@@ -1651,12 +1626,8 @@ test_32bits_limit(int fd)
 
 	for (i = 0; i < ARRAY_SIZE(points); i++) {
 		int fence = sw_sync_timeline_create_fence(timeline, i + 1);
-		uint32_t tmp_syncobj = syncobj_create(fd, 0);
-
-		syncobj_import_sync_file(fd, tmp_syncobj, fence);
-		syncobj_binary_to_timeline(fd, thread_data.syncobj, points[i], tmp_syncobj);
+		syncobj_import_sync_file(fd, thread_data.syncobj, fence, points[i]);
 		close(fence);
-		syncobj_destroy(fd, tmp_syncobj);
 	}
 
 	last_value = 0;
diff --git a/tests/syncobj_wait.c b/tests/syncobj_wait.c
index e0ff69b79..a623af3f3 100644
--- a/tests/syncobj_wait.c
+++ b/tests/syncobj_wait.c
@@ -217,7 +217,7 @@ syncobj_attach_sw_sync(int fd, uint32_t handle)
 
 	timeline = sw_sync_timeline_create();
 	fence = sw_sync_timeline_create_fence(timeline, 1);
-	syncobj_import_sync_file(fd, handle, fence);
+	syncobj_import_sync_file(fd, handle, fence, 0);
 	close(fence);
 
 	return timeline;
diff --git a/tests/xe/xe_dma_buf_sync.c b/tests/xe/xe_dma_buf_sync.c
index c08f8ac18..7127242ae 100644
--- a/tests/xe/xe_dma_buf_sync.c
+++ b/tests/xe/xe_dma_buf_sync.c
@@ -175,7 +175,7 @@ test_export_dma_buf(struct drm_xe_engine_class_instance *hwe0,
 
 		/* Convert sync file to syncobj */
 		syncobj = syncobj_create(fd[1], 0);
-		syncobj_import_sync_file(fd[1], syncobj, sync_fd);
+		syncobj_import_sync_file(fd[1], syncobj, sync_fd, 0);
 
 		/* Do an exec with syncobj as in fence on FD[1] */
 		data[i]->batch[b++] = MI_STORE_DWORD_IMM_GEN4;
-- 
GitLab