diff options
author | Christian König <ckoenig.leichtzumerken@gmail.com> | 2019-04-01 17:50:56 +0800 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2019-04-01 12:05:53 +0200 |
commit | 44f8a1396e83f1030eaf18591b3f106235118a64 (patch) | |
tree | 84f28ed5b50ee90db07a8b9f30885374a25ebe59 /drivers/gpu/drm/drm_syncobj.c | |
parent | 7bf60c52e093d9309752dbc3569fa213a80fb815 (diff) |
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
Diffstat (limited to 'drivers/gpu/drm/drm_syncobj.c')
-rw-r--r-- | drivers/gpu/drm/drm_syncobj.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 5329e66598c6..dbe4a1c75fbc 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -123,6 +123,46 @@ static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj, } /** + * 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 * @fence: fence to install in sync file. |