Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Christian König and committed by
Christian König
44f8a139 7bf60c52

+45
+40
drivers/gpu/drm/drm_syncobj.c
··· 123 123 } 124 124 125 125 /** 126 + * drm_syncobj_add_point - add new timeline point to the syncobj 127 + * @syncobj: sync object to add timeline point do 128 + * @chain: chain node to use to add the point 129 + * @fence: fence to encapsulate in the chain node 130 + * @point: sequence number to use for the point 131 + * 132 + * Add the chain node as new timeline point to the syncobj. 133 + */ 134 + void drm_syncobj_add_point(struct drm_syncobj *syncobj, 135 + struct dma_fence_chain *chain, 136 + struct dma_fence *fence, 137 + uint64_t point) 138 + { 139 + struct syncobj_wait_entry *cur, *tmp; 140 + struct dma_fence *prev; 141 + 142 + dma_fence_get(fence); 143 + 144 + spin_lock(&syncobj->lock); 145 + 146 + prev = drm_syncobj_fence_get(syncobj); 147 + /* You are adding an unorder point to timeline, which could cause payload returned from query_ioctl is 0! */ 148 + if (prev && prev->seqno >= point) 149 + DRM_ERROR("You are adding an unorder point to timeline!\n"); 150 + dma_fence_chain_init(chain, prev, fence, point); 151 + rcu_assign_pointer(syncobj->fence, &chain->base); 152 + 153 + list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) { 154 + list_del_init(&cur->node); 155 + syncobj_wait_syncobj_func(syncobj, cur); 156 + } 157 + spin_unlock(&syncobj->lock); 158 + 159 + /* Walk the chain once to trigger garbage collection */ 160 + dma_fence_chain_for_each(fence, prev); 161 + dma_fence_put(prev); 162 + } 163 + EXPORT_SYMBOL(drm_syncobj_add_point); 164 + 165 + /** 126 166 * drm_syncobj_replace_fence - replace fence in a sync object. 127 167 * @syncobj: Sync object to replace fence in 128 168 * @fence: fence to install in sync file.
+5
include/drm/drm_syncobj.h
··· 27 27 #define __DRM_SYNCOBJ_H__ 28 28 29 29 #include <linux/dma-fence.h> 30 + #include <linux/dma-fence-chain.h> 30 31 31 32 struct drm_file; 32 33 ··· 113 112 114 113 struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, 115 114 u32 handle); 115 + void drm_syncobj_add_point(struct drm_syncobj *syncobj, 116 + struct dma_fence_chain *chain, 117 + struct dma_fence *fence, 118 + uint64_t point); 116 119 void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, 117 120 struct dma_fence *fence); 118 121 int drm_syncobj_find_fence(struct drm_file *file_private,