mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	drm/syncobj: add timeline payload query ioctl v6
user mode can query timeline payload. v2: check return value of copy_to_user v3: handle querying entry by entry v4: rebase on new chain container, simplify interface v5: query last signaled timeline point, not last point. v6: add unorder point check Signed-off-by: Chunming Zhou <david1.zhou@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com> Cc: Tobias Hector <Tobias.Hector@amd.com> Cc: Jason Ekstrand <jason@jlekstrand.net> Cc: Dave Airlie <airlied@redhat.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Link: https://patchwork.freedesktop.org/patch/295784/?series=58813&rev=1
This commit is contained in:
		
							parent
							
								
									01d6c35783
								
							
						
					
					
						commit
						27b575a9aa
					
				
					 4 changed files with 76 additions and 0 deletions
				
			
		|  | @ -188,6 +188,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, | |||
| 			    struct drm_file *file_private); | ||||
| int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, | ||||
| 			     struct drm_file *file_private); | ||||
| int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, | ||||
| 			    struct drm_file *file_private); | ||||
| 
 | ||||
| /* drm_framebuffer.c */ | ||||
| void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent, | ||||
|  |  | |||
|  | @ -694,6 +694,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { | |||
| 		      DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl, | ||||
| 		      DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl, | ||||
| 		      DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED), | ||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED), | ||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_UNLOCKED), | ||||
|  |  | |||
|  | @ -1065,3 +1065,65 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, | |||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, | ||||
| 			    struct drm_file *file_private) | ||||
| { | ||||
| 	struct drm_syncobj_timeline_array *args = data; | ||||
| 	struct drm_syncobj **syncobjs; | ||||
| 	uint64_t __user *points = u64_to_user_ptr(args->points); | ||||
| 	uint32_t i; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	if (args->pad != 0) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (args->count_handles == 0) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	ret = drm_syncobj_array_find(file_private, | ||||
| 				     u64_to_user_ptr(args->handles), | ||||
| 				     args->count_handles, | ||||
| 				     &syncobjs); | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	for (i = 0; i < args->count_handles; i++) { | ||||
| 		struct dma_fence_chain *chain; | ||||
| 		struct dma_fence *fence; | ||||
| 		uint64_t point; | ||||
| 
 | ||||
| 		fence = drm_syncobj_fence_get(syncobjs[i]); | ||||
| 		chain = to_dma_fence_chain(fence); | ||||
| 		if (chain) { | ||||
| 			struct dma_fence *iter, *last_signaled = NULL; | ||||
| 
 | ||||
| 			dma_fence_chain_for_each(iter, fence) { | ||||
| 				if (!iter) | ||||
| 					break; | ||||
| 				dma_fence_put(last_signaled); | ||||
| 				last_signaled = dma_fence_get(iter); | ||||
| 				if (!to_dma_fence_chain(last_signaled)->prev_seqno) | ||||
| 					/* It is most likely that timeline has
 | ||||
| 					 * unorder points. */ | ||||
| 					break; | ||||
| 			} | ||||
| 			point = dma_fence_is_signaled(last_signaled) ? | ||||
| 				last_signaled->seqno : | ||||
| 				to_dma_fence_chain(last_signaled)->prev_seqno; | ||||
| 			dma_fence_put(last_signaled); | ||||
| 		} else { | ||||
| 			point = 0; | ||||
| 		} | ||||
| 		ret = copy_to_user(&points[i], &point, sizeof(uint64_t)); | ||||
| 		ret = ret ? -EFAULT : 0; | ||||
| 		if (ret) | ||||
| 			break; | ||||
| 	} | ||||
| 	drm_syncobj_array_free(syncobjs, args->count_handles); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
|  |  | |||
|  | @ -767,6 +767,14 @@ struct drm_syncobj_array { | |||
| 	__u32 pad; | ||||
| }; | ||||
| 
 | ||||
| struct drm_syncobj_timeline_array { | ||||
| 	__u64 handles; | ||||
| 	__u64 points; | ||||
| 	__u32 count_handles; | ||||
| 	__u32 pad; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* Query current scanout sequence number */ | ||||
| struct drm_crtc_get_sequence { | ||||
| 	__u32 crtc_id;		/* requested crtc_id */ | ||||
|  | @ -924,6 +932,8 @@ extern "C" { | |||
| #define DRM_IOCTL_MODE_REVOKE_LEASE	DRM_IOWR(0xC9, struct drm_mode_revoke_lease) | ||||
| 
 | ||||
| #define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT	DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait) | ||||
| #define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array) | ||||
| 
 | ||||
| /**
 | ||||
|  * Device specific ioctls should only be in their respective headers | ||||
|  * The device specific ioctl range is from 0x40 to 0x9f. | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Chunming Zhou
						Chunming Zhou