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:
Christian König 2019-04-01 17:50:56 +08:00 committed by Christian König
parent 7bf60c52e0
commit 44f8a1396e
2 changed files with 45 additions and 0 deletions

View File

@ -122,6 +122,46 @@ static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj,
spin_unlock(&syncobj->lock); 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. * drm_syncobj_replace_fence - replace fence in a sync object.
* @syncobj: Sync object to replace fence in * @syncobj: Sync object to replace fence in

View File

@ -27,6 +27,7 @@
#define __DRM_SYNCOBJ_H__ #define __DRM_SYNCOBJ_H__
#include <linux/dma-fence.h> #include <linux/dma-fence.h>
#include <linux/dma-fence-chain.h>
struct drm_file; 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, struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
u32 handle); 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, void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
struct dma_fence *fence); struct dma_fence *fence);
int drm_syncobj_find_fence(struct drm_file *file_private, int drm_syncobj_find_fence(struct drm_file *file_private,