diff mbox series

[13/15] drm: add user fence support to drm_syncobj

Message ID 20220502163722.3957-14-christian.koenig@amd.com
State New
Headers show
Series [01/15] dma-buf: rename DMA_FENCE_FLAG_USER_BITS to _DEVICE | expand

Commit Message

Christian König May 2, 2022, 4:37 p.m. UTC
For now just filter or wait for user fences.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/drm_syncobj.c | 15 ++++++++++++---
 include/drm/drm_syncobj.h     | 25 +++++++++++++++++++++----
 2 files changed, 33 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 5a961ea90a35..8d25a2dd107b 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -386,7 +386,7 @@  int drm_syncobj_find_fence(struct drm_file *file_private,
 	struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
 	struct syncobj_wait_entry wait;
 	u64 timeout = nsecs_to_jiffies64(DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT);
-	int ret;
+	long ret;
 
 	if (!syncobj)
 		return -ENOENT;
@@ -398,10 +398,19 @@  int drm_syncobj_find_fence(struct drm_file *file_private,
 	if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
 		might_sleep();
 		lockdep_assert_none_held_once();
+		*fence = drm_syncobj_user_fence_get(syncobj);
+		if (*fence) {
+			ret = dma_fence_wait_user(*fence, timeout);
+			if (ret < 0)
+				return ret;
+			if (ret == 0)
+				return -ETIME;
+			timeout = ret;
+		}
+	} else {
+		*fence = drm_syncobj_fence_get(syncobj);
 	}
 
-	*fence = drm_syncobj_fence_get(syncobj);
-
 	if (*fence) {
 		ret = dma_fence_chain_find_seqno(fence, point);
 		if (!ret) {
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index 6cf7243a1dc5..acc3979815eb 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -28,6 +28,7 @@ 
 
 #include <linux/dma-fence.h>
 #include <linux/dma-fence-chain.h>
+#include <linux/dma-fence-unwrap.h>
 
 struct drm_file;
 
@@ -89,18 +90,18 @@  drm_syncobj_put(struct drm_syncobj *obj)
 }
 
 /**
- * drm_syncobj_fence_get - get a reference to a fence in a sync object
+ * drm_syncobj_user_fence_get - get an user fence from a sync object
  * @syncobj: sync object.
  *
  * This acquires additional reference to &drm_syncobj.fence contained in @obj,
- * if not NULL. It is illegal to call this without already holding a reference.
- * No locks required.
+ * if not NULL. It is illegal to call this without holding a reference to the
+ * syncobj. No locks required.
  *
  * Returns:
  * Either the fence of @obj or NULL if there's none.
  */
 static inline struct dma_fence *
-drm_syncobj_fence_get(struct drm_syncobj *syncobj)
+drm_syncobj_user_fence_get(struct drm_syncobj *syncobj)
 {
 	struct dma_fence *fence;
 
@@ -111,6 +112,22 @@  drm_syncobj_fence_get(struct drm_syncobj *syncobj)
 	return fence;
 }
 
+/**
+ * drm_syncobj_fence_get - get a reference to a fence in a sync object
+ * @syncobj: sync object.
+ *
+ * Same functionality as drm_syncobj_user_fence_get(), but user fences are
+ * filtered out.
+ *
+ * Returns:
+ * Either the fence of @obj or NULL if there's none.
+ */
+static inline struct dma_fence *
+drm_syncobj_fence_get(struct drm_syncobj *syncobj)
+{
+	return dma_fence_filter_user(drm_syncobj_user_fence_get(syncobj));
+}
+
 struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
 				     u32 handle);
 void drm_syncobj_add_point(struct drm_syncobj *syncobj,