mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	drm: Add a drm_gem_objects_lookup helper
Similar to the single handle drm_gem_object_lookup(), drm_gem_objects_lookup() takes an array of handles and returns an array of GEM objects. v2: - Take the userspace pointer directly and allocate the array. - Expand the function documentation. Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <maxime.ripard@bootlin.com> Cc: Sean Paul <sean@poorly.run> Cc: David Airlie <airlied@linux.ie> Cc: Daniel Vetter <daniel@ffwll.ch> Acked-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Acked-by: Tomeu Vizoso <tomeu.vizoso@collabora.com> Signed-off-by: Rob Herring <robh@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20190409205427.6943-3-robh@kernel.org
This commit is contained in:
		
							parent
							
								
									d08d42de64
								
							
						
					
					
						commit
						c117aa4d87
					
				
					 2 changed files with 85 additions and 10 deletions
				
			
		|  | @ -646,6 +646,85 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(drm_gem_put_pages); | EXPORT_SYMBOL(drm_gem_put_pages); | ||||||
| 
 | 
 | ||||||
|  | static int objects_lookup(struct drm_file *filp, u32 *handle, int count, | ||||||
|  | 			  struct drm_gem_object **objs) | ||||||
|  | { | ||||||
|  | 	int i, ret = 0; | ||||||
|  | 	struct drm_gem_object *obj; | ||||||
|  | 
 | ||||||
|  | 	spin_lock(&filp->table_lock); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < count; i++) { | ||||||
|  | 		/* Check if we currently have a reference on the object */ | ||||||
|  | 		obj = idr_find(&filp->object_idr, handle[i]); | ||||||
|  | 		if (!obj) { | ||||||
|  | 			ret = -ENOENT; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		drm_gem_object_get(obj); | ||||||
|  | 		objs[i] = obj; | ||||||
|  | 	} | ||||||
|  | 	spin_unlock(&filp->table_lock); | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * drm_gem_objects_lookup - look up GEM objects from an array of handles | ||||||
|  |  * @filp: DRM file private date | ||||||
|  |  * @bo_handles: user pointer to array of userspace handle | ||||||
|  |  * @count: size of handle array | ||||||
|  |  * @objs_out: returned pointer to array of drm_gem_object pointers | ||||||
|  |  * | ||||||
|  |  * Takes an array of userspace handles and returns a newly allocated array of | ||||||
|  |  * GEM objects. | ||||||
|  |  * | ||||||
|  |  * For a single handle lookup, use drm_gem_object_lookup(). | ||||||
|  |  * | ||||||
|  |  * Returns: | ||||||
|  |  * | ||||||
|  |  * @objs filled in with GEM object pointers. Returned GEM objects need to be | ||||||
|  |  * released with drm_gem_object_put(). -ENOENT is returned on a lookup | ||||||
|  |  * failure. 0 is returned on success. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles, | ||||||
|  | 			   int count, struct drm_gem_object ***objs_out) | ||||||
|  | { | ||||||
|  | 	int ret; | ||||||
|  | 	u32 *handles; | ||||||
|  | 	struct drm_gem_object **objs; | ||||||
|  | 
 | ||||||
|  | 	if (!count) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	objs = kvmalloc_array(count, sizeof(struct drm_gem_object *), | ||||||
|  | 			     GFP_KERNEL | __GFP_ZERO); | ||||||
|  | 	if (!objs) | ||||||
|  | 		return -ENOMEM; | ||||||
|  | 
 | ||||||
|  | 	handles = kvmalloc_array(count, sizeof(u32), GFP_KERNEL); | ||||||
|  | 	if (!handles) { | ||||||
|  | 		ret = -ENOMEM; | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (copy_from_user(handles, bo_handles, count * sizeof(u32))) { | ||||||
|  | 		ret = -EFAULT; | ||||||
|  | 		DRM_DEBUG("Failed to copy in GEM handles\n"); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret = objects_lookup(filp, handles, count, objs); | ||||||
|  | 	*objs_out = objs; | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	kvfree(handles); | ||||||
|  | 	return ret; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(drm_gem_objects_lookup); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * drm_gem_object_lookup - look up a GEM object from its handle |  * drm_gem_object_lookup - look up a GEM object from its handle | ||||||
|  * @filp: DRM file private date |  * @filp: DRM file private date | ||||||
|  | @ -655,21 +734,15 @@ EXPORT_SYMBOL(drm_gem_put_pages); | ||||||
|  * |  * | ||||||
|  * A reference to the object named by the handle if such exists on @filp, NULL |  * A reference to the object named by the handle if such exists on @filp, NULL | ||||||
|  * otherwise. |  * otherwise. | ||||||
|  |  * | ||||||
|  |  * If looking up an array of handles, use drm_gem_objects_lookup(). | ||||||
|  */ |  */ | ||||||
| struct drm_gem_object * | struct drm_gem_object * | ||||||
| drm_gem_object_lookup(struct drm_file *filp, u32 handle) | drm_gem_object_lookup(struct drm_file *filp, u32 handle) | ||||||
| { | { | ||||||
| 	struct drm_gem_object *obj; | 	struct drm_gem_object *obj = NULL; | ||||||
| 
 |  | ||||||
| 	spin_lock(&filp->table_lock); |  | ||||||
| 
 |  | ||||||
| 	/* Check if we currently have a reference on the object */ |  | ||||||
| 	obj = idr_find(&filp->object_idr, handle); |  | ||||||
| 	if (obj) |  | ||||||
| 		drm_gem_object_get(obj); |  | ||||||
| 
 |  | ||||||
| 	spin_unlock(&filp->table_lock); |  | ||||||
| 
 | 
 | ||||||
|  | 	objects_lookup(filp, &handle, 1, &obj); | ||||||
| 	return obj; | 	return obj; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(drm_gem_object_lookup); | EXPORT_SYMBOL(drm_gem_object_lookup); | ||||||
|  |  | ||||||
|  | @ -381,6 +381,8 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj); | ||||||
| void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, | void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, | ||||||
| 		bool dirty, bool accessed); | 		bool dirty, bool accessed); | ||||||
| 
 | 
 | ||||||
|  | int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles, | ||||||
|  | 			   int count, struct drm_gem_object ***objs_out); | ||||||
| struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle); | struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle); | ||||||
| long drm_gem_reservation_object_wait(struct drm_file *filep, u32 handle, | long drm_gem_reservation_object_wait(struct drm_file *filep, u32 handle, | ||||||
| 				    bool wait_all, unsigned long timeout); | 				    bool wait_all, unsigned long timeout); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Rob Herring
						Rob Herring