mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									7513ce4902
								
							
						
					
					
						commit
						fd921693fe
					
				
					 3 changed files with 46 additions and 7 deletions
				
			
		|  | @ -123,7 +123,9 @@ static const struct dma_fence_ops dma_fence_stub_ops = { | |||
| /**
 | ||||
|  * dma_fence_get_stub - return a signaled fence | ||||
|  * | ||||
|  * Return a stub fence which is already signaled. | ||||
|  * Return a stub fence which is already signaled. The fence's | ||||
|  * timestamp corresponds to the first time after boot this | ||||
|  * function is called. | ||||
|  */ | ||||
| struct dma_fence *dma_fence_get_stub(void) | ||||
| { | ||||
|  | @ -141,6 +143,29 @@ struct dma_fence *dma_fence_get_stub(void) | |||
| } | ||||
| EXPORT_SYMBOL(dma_fence_get_stub); | ||||
| 
 | ||||
| /**
 | ||||
|  * dma_fence_allocate_private_stub - return a private, signaled fence | ||||
|  * | ||||
|  * Return a newly allocated and signaled stub fence. | ||||
|  */ | ||||
| struct dma_fence *dma_fence_allocate_private_stub(void) | ||||
| { | ||||
| 	struct dma_fence *fence; | ||||
| 
 | ||||
| 	fence = kzalloc(sizeof(*fence), GFP_KERNEL); | ||||
| 	if (fence == NULL) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 
 | ||||
| 	dma_fence_init(fence, | ||||
| 		       &dma_fence_stub_ops, | ||||
| 		       &dma_fence_stub_lock, | ||||
| 		       0, 0); | ||||
| 	dma_fence_signal(fence); | ||||
| 
 | ||||
| 	return fence; | ||||
| } | ||||
| EXPORT_SYMBOL(dma_fence_allocate_private_stub); | ||||
| 
 | ||||
| /**
 | ||||
|  * dma_fence_context_alloc - allocate an array of fence contexts | ||||
|  * @num: amount of contexts to allocate | ||||
|  |  | |||
|  | @ -350,12 +350,16 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence); | |||
|  * | ||||
|  * Assign a already signaled stub fence to the sync object. | ||||
|  */ | ||||
| static void drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) | ||||
| static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) | ||||
| { | ||||
| 	struct dma_fence *fence = dma_fence_get_stub(); | ||||
| 	struct dma_fence *fence = dma_fence_allocate_private_stub(); | ||||
| 
 | ||||
| 	if (IS_ERR(fence)) | ||||
| 		return PTR_ERR(fence); | ||||
| 
 | ||||
| 	drm_syncobj_replace_fence(syncobj, fence); | ||||
| 	dma_fence_put(fence); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* 5s default for wait submission */ | ||||
|  | @ -478,6 +482,7 @@ EXPORT_SYMBOL(drm_syncobj_free); | |||
| int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, | ||||
| 		       struct dma_fence *fence) | ||||
| { | ||||
| 	int ret; | ||||
| 	struct drm_syncobj *syncobj; | ||||
| 
 | ||||
| 	syncobj = kzalloc(sizeof(struct drm_syncobj), GFP_KERNEL); | ||||
|  | @ -488,8 +493,13 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, | |||
| 	INIT_LIST_HEAD(&syncobj->cb_list); | ||||
| 	spin_lock_init(&syncobj->lock); | ||||
| 
 | ||||
| 	if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) | ||||
| 		drm_syncobj_assign_null_handle(syncobj); | ||||
| 	if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) { | ||||
| 		ret = drm_syncobj_assign_null_handle(syncobj); | ||||
| 		if (ret < 0) { | ||||
| 			drm_syncobj_put(syncobj); | ||||
| 			return ret; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (fence) | ||||
| 		drm_syncobj_replace_fence(syncobj, fence); | ||||
|  | @ -1334,8 +1344,11 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, | |||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	for (i = 0; i < args->count_handles; i++) | ||||
| 		drm_syncobj_assign_null_handle(syncobjs[i]); | ||||
| 	for (i = 0; i < args->count_handles; i++) { | ||||
| 		ret = drm_syncobj_assign_null_handle(syncobjs[i]); | ||||
| 		if (ret < 0) | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	drm_syncobj_array_free(syncobjs, args->count_handles); | ||||
| 
 | ||||
|  |  | |||
|  | @ -587,6 +587,7 @@ static inline signed long dma_fence_wait(struct dma_fence *fence, bool intr) | |||
| } | ||||
| 
 | ||||
| struct dma_fence *dma_fence_get_stub(void); | ||||
| struct dma_fence *dma_fence_allocate_private_stub(void); | ||||
| u64 dma_fence_context_alloc(unsigned num); | ||||
| 
 | ||||
| #define DMA_FENCE_TRACE(f, fmt, args...) \ | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 David Stevens
						David Stevens