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

drm/syncobj: use newly allocated stub fences

Allocate a new private stub fence in drm_syncobj_assign_null_handle,
instead of using a static stub fence.

When userspace creates a fence with DRM_SYNCOBJ_CREATE_SIGNALED or when
userspace signals a fence via DRM_IOCTL_SYNCOBJ_SIGNAL, the timestamp
obtained when the fence is exported and queried with SYNC_IOC_FILE_INFO
should match when the fence's status was changed from the perspective of
userspace, which is during the respective ioctl.

When a static stub fence started being used in by these ioctls, this
behavior changed. Instead, the timestamp returned by SYNC_IOC_FILE_INFO
became the first time anything used the static stub fence, which has no
meaning to userspace.

Signed-off-by: David Stevens <stevensd@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210408095428.3983055-1-stevensd@google.com
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Christian König <christian.koenig@amd.com>

authored by

David Stevens and committed by
Christian König
fd921693 7513ce49

+46 -7
+26 -1
drivers/dma-buf/dma-fence.c
··· 123 123 /** 124 124 * dma_fence_get_stub - return a signaled fence 125 125 * 126 - * Return a stub fence which is already signaled. 126 + * Return a stub fence which is already signaled. The fence's 127 + * timestamp corresponds to the first time after boot this 128 + * function is called. 127 129 */ 128 130 struct dma_fence *dma_fence_get_stub(void) 129 131 { ··· 142 140 return dma_fence_get(&dma_fence_stub); 143 141 } 144 142 EXPORT_SYMBOL(dma_fence_get_stub); 143 + 144 + /** 145 + * dma_fence_allocate_private_stub - return a private, signaled fence 146 + * 147 + * Return a newly allocated and signaled stub fence. 148 + */ 149 + struct dma_fence *dma_fence_allocate_private_stub(void) 150 + { 151 + struct dma_fence *fence; 152 + 153 + fence = kzalloc(sizeof(*fence), GFP_KERNEL); 154 + if (fence == NULL) 155 + return ERR_PTR(-ENOMEM); 156 + 157 + dma_fence_init(fence, 158 + &dma_fence_stub_ops, 159 + &dma_fence_stub_lock, 160 + 0, 0); 161 + dma_fence_signal(fence); 162 + 163 + return fence; 164 + } 165 + EXPORT_SYMBOL(dma_fence_allocate_private_stub); 145 166 146 167 /** 147 168 * dma_fence_context_alloc - allocate an array of fence contexts
+19 -6
drivers/gpu/drm/drm_syncobj.c
··· 350 350 * 351 351 * Assign a already signaled stub fence to the sync object. 352 352 */ 353 - static void drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) 353 + static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) 354 354 { 355 - struct dma_fence *fence = dma_fence_get_stub(); 355 + struct dma_fence *fence = dma_fence_allocate_private_stub(); 356 + 357 + if (IS_ERR(fence)) 358 + return PTR_ERR(fence); 356 359 357 360 drm_syncobj_replace_fence(syncobj, fence); 358 361 dma_fence_put(fence); 362 + return 0; 359 363 } 360 364 361 365 /* 5s default for wait submission */ ··· 482 478 int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, 483 479 struct dma_fence *fence) 484 480 { 481 + int ret; 485 482 struct drm_syncobj *syncobj; 486 483 487 484 syncobj = kzalloc(sizeof(struct drm_syncobj), GFP_KERNEL); ··· 493 488 INIT_LIST_HEAD(&syncobj->cb_list); 494 489 spin_lock_init(&syncobj->lock); 495 490 496 - if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) 497 - drm_syncobj_assign_null_handle(syncobj); 491 + if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) { 492 + ret = drm_syncobj_assign_null_handle(syncobj); 493 + if (ret < 0) { 494 + drm_syncobj_put(syncobj); 495 + return ret; 496 + } 497 + } 498 498 499 499 if (fence) 500 500 drm_syncobj_replace_fence(syncobj, fence); ··· 1344 1334 if (ret < 0) 1345 1335 return ret; 1346 1336 1347 - for (i = 0; i < args->count_handles; i++) 1348 - drm_syncobj_assign_null_handle(syncobjs[i]); 1337 + for (i = 0; i < args->count_handles; i++) { 1338 + ret = drm_syncobj_assign_null_handle(syncobjs[i]); 1339 + if (ret < 0) 1340 + break; 1341 + } 1349 1342 1350 1343 drm_syncobj_array_free(syncobjs, args->count_handles); 1351 1344
+1
include/linux/dma-fence.h
··· 587 587 } 588 588 589 589 struct dma_fence *dma_fence_get_stub(void); 590 + struct dma_fence *dma_fence_allocate_private_stub(void); 590 591 u64 dma_fence_context_alloc(unsigned num); 591 592 592 593 #define DMA_FENCE_TRACE(f, fmt, args...) \