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

drm/syncobj: use the timeline point in drm_syncobj_find_fence v4

Implement finding the right timeline point in drm_syncobj_find_fence.

v2: return -EINVAL when the point is not submitted yet.
v3: fix reference counting bug, add flags handling as well
v4: add timeout for find fence

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/295786/?series=58813&rev=1

authored by

Christian König and committed by
Christian König
bc9c80fe 27b575a9

+47 -3
+47 -3
drivers/gpu/drm/drm_syncobj.c
··· 214 214 dma_fence_put(fence); 215 215 } 216 216 217 + /* 5s default for wait submission */ 218 + #define DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT 5000000000ULL 217 219 /** 218 220 * drm_syncobj_find_fence - lookup and reference the fence in a sync object 219 221 * @file_private: drm file private pointer ··· 236 234 struct dma_fence **fence) 237 235 { 238 236 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); 239 - int ret = 0; 237 + struct syncobj_wait_entry wait; 238 + u64 timeout = nsecs_to_jiffies64(DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT); 239 + int ret; 240 240 241 241 if (!syncobj) 242 242 return -ENOENT; 243 243 244 244 *fence = drm_syncobj_fence_get(syncobj); 245 - if (!*fence) { 245 + drm_syncobj_put(syncobj); 246 + 247 + if (*fence) { 248 + ret = dma_fence_chain_find_seqno(fence, point); 249 + if (!ret) 250 + return 0; 251 + dma_fence_put(*fence); 252 + } else { 246 253 ret = -EINVAL; 247 254 } 248 - drm_syncobj_put(syncobj); 255 + 256 + if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) 257 + return ret; 258 + 259 + memset(&wait, 0, sizeof(wait)); 260 + wait.task = current; 261 + wait.point = point; 262 + drm_syncobj_fence_add_wait(syncobj, &wait); 263 + 264 + do { 265 + set_current_state(TASK_INTERRUPTIBLE); 266 + if (wait.fence) { 267 + ret = 0; 268 + break; 269 + } 270 + if (timeout == 0) { 271 + ret = -ETIME; 272 + break; 273 + } 274 + 275 + if (signal_pending(current)) { 276 + ret = -ERESTARTSYS; 277 + break; 278 + } 279 + 280 + timeout = schedule_timeout(timeout); 281 + } while (1); 282 + 283 + __set_current_state(TASK_RUNNING); 284 + *fence = wait.fence; 285 + 286 + if (wait.node.next) 287 + drm_syncobj_remove_wait(syncobj, &wait); 288 + 249 289 return ret; 250 290 } 251 291 EXPORT_SYMBOL(drm_syncobj_find_fence);