Use the dma_fence_chain object to create a timeline of fence objects
instead of just replacing the existing fence.

Signed-off-by: Christian König <christian.koe...@amd.com>
---
 drivers/gpu/drm/drm_syncobj.c | 40 ++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_syncobj.h     |  5 +++++
 2 files changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 4a2e6ef16979..589d884ccd58 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -193,6 +193,46 @@ void drm_syncobj_remove_callback(struct drm_syncobj 
*syncobj,
        spin_unlock(&syncobj->lock);
 }
 
+/**
+ * drm_syncobj_add_point - add new timeline point to the syncobj
+ * @syncobj: sync object to add timeline point do
+ * @chain: chain node to use to add the point
+ * @fence: fence to encapsulate in the chain node
+ * @point: sequence number to use for the point
+ *
+ * Add the chain node as new timeline point to the syncobj.
+ */
+void drm_syncobj_add_point(struct drm_syncobj *syncobj,
+                          struct dma_fence_chain *chain,
+                          struct dma_fence *fence,
+                          uint64_t point)
+{
+       struct drm_syncobj_cb *cur, *tmp;
+       struct dma_fence *prev;
+
+       dma_fence_get(fence);
+       dma_fence_get(fence);
+
+       spin_lock(&syncobj->lock);
+
+       prev = rcu_dereference_protected(syncobj->fence,
+                                        lockdep_is_held(&syncobj->lock));
+       dma_fence_chain_init(chain, prev, fence, point);
+       rcu_assign_pointer(syncobj->fence, &chain->base);
+
+       list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) {
+               list_del_init(&cur->node);
+               cur->func(syncobj, cur);
+       }
+       spin_unlock(&syncobj->lock);
+
+       /* Walk the chain once to trigger garbage collection */
+       prev = fence;
+       dma_fence_chain_for_each(prev);
+
+       dma_fence_put(fence);
+}
+
 /**
  * drm_syncobj_replace_fence - replace fence in a sync object.
  * @syncobj: Sync object to replace fence in
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index c79f5ada7cdb..35a917241e30 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -27,6 +27,7 @@
 #define __DRM_SYNCOBJ_H__
 
 #include "linux/dma-fence.h"
+#include "linux/dma-fence-chain.h"
 
 /**
  * struct drm_syncobj - sync object.
@@ -110,6 +111,10 @@ drm_syncobj_fence_get(struct drm_syncobj *syncobj)
 
 struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
                                     u32 handle);
+void drm_syncobj_add_point(struct drm_syncobj *syncobj,
+                          struct dma_fence_chain *chain,
+                          struct dma_fence *fence,
+                          uint64_t point);
 void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
                               struct dma_fence *fence);
 int drm_syncobj_find_fence(struct drm_file *file_private,
-- 
2.14.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to