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