[05/10] drm/syncobj: add new drm_syncobj_add_point interface v2

Submitted by Christian König on Dec. 4, 2018, 11:59 a.m.

Details

Message ID 20181204115948.15202-5-christian.koenig@amd.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in DRI devel

Not browsing as part of any series.

Commit Message

Christian König Dec. 4, 2018, 11:59 a.m.
Use the dma_fence_chain object to create a timeline of fence objects
instead of just replacing the existing fence.

v2: rebase and cleanup

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

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index e19525af0cce..64fcfea1c39f 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -122,6 +122,43 @@  static void drm_syncobj_remove_wait(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 syncobj_wait_entry *cur, *tmp;
+	struct dma_fence *prev;
+
+	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);
+		syncobj_wait_syncobj_func(syncobj, cur);
+	}
+	spin_unlock(&syncobj->lock);
+
+	/* Walk the chain once to trigger garbage collection */
+	dma_fence_chain_for_each(fence);
+}
+EXPORT_SYMBOL(drm_syncobj_add_point);
+
 /**
  * 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 7c6ed845c70d..8acb4ae4f311 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,

Comments

在 2018/12/4 19:59, Christian König 写道:
> Use the dma_fence_chain object to create a timeline of fence objects

> instead of just replacing the existing fence.

>

> v2: rebase and cleanup

>

> Signed-off-by: Christian König <christian.koenig@amd.com>


Reviewed-by: Chunming Zhou <david1.zhou@amd.com>


> ---

>   drivers/gpu/drm/drm_syncobj.c | 37 +++++++++++++++++++++++++++++++++++++

>   include/drm/drm_syncobj.h     |  5 +++++

>   2 files changed, 42 insertions(+)

>

> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c

> index e19525af0cce..64fcfea1c39f 100644

> --- a/drivers/gpu/drm/drm_syncobj.c

> +++ b/drivers/gpu/drm/drm_syncobj.c

> @@ -122,6 +122,43 @@ static void drm_syncobj_remove_wait(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 syncobj_wait_entry *cur, *tmp;

> +	struct dma_fence *prev;

> +

> +	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);

> +		syncobj_wait_syncobj_func(syncobj, cur);

> +	}

> +	spin_unlock(&syncobj->lock);

> +

> +	/* Walk the chain once to trigger garbage collection */

> +	dma_fence_chain_for_each(fence);

> +}

> +EXPORT_SYMBOL(drm_syncobj_add_point);

> +

>   /**

>    * 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 7c6ed845c70d..8acb4ae4f311 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,