drm/syncobj: add new drm_syncobj_add_point interface v4
Use the dma_fence_chain object to create a timeline of fence objects instead of just replacing the existing fence. v2: rebase and cleanup v3: fix garbage collection parameters v4: add unorder point check, print a warn calltrace Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Link: https://patchwork.freedesktop.org/patch/295780/?series=58813&rev=1
This commit is contained in:
parent
7bf60c52e0
commit
44f8a1396e
@ -122,6 +122,46 @@ 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 = drm_syncobj_fence_get(syncobj);
|
||||
/* You are adding an unorder point to timeline, which could cause payload returned from query_ioctl is 0! */
|
||||
if (prev && prev->seqno >= point)
|
||||
DRM_ERROR("You are adding an unorder point to timeline!\n");
|
||||
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, prev);
|
||||
dma_fence_put(prev);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_syncobj_add_point);
|
||||
|
||||
/**
|
||||
* drm_syncobj_replace_fence - replace fence in a sync object.
|
||||
* @syncobj: Sync object to replace fence in
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define __DRM_SYNCOBJ_H__
|
||||
|
||||
#include <linux/dma-fence.h>
|
||||
#include <linux/dma-fence-chain.h>
|
||||
|
||||
struct drm_file;
|
||||
|
||||
@ -112,6 +113,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,
|
||||
|
Loading…
Reference in New Issue
Block a user