mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	drm: Add helpers for setting up an array of dma_fence dependencies.
I needed to add implicit dependency support for v3d, and Rob Herring
has been working on it for panfrost, and I had recently looked at the
lima implementation so I think this will be a good intersection of
what we all want and simplify our scheduler implementations.
v2: Rebase on xa_limit_32b API change, and tiny checkpatch cleanups on
    the way in (unsigned int vs unsigned, extra return before
    EXPORT_SYMBOL_GPL)
Signed-off-by: Eric Anholt <eric@anholt.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20190401222635.25013-6-eric@anholt.net
Reviewed-and-tested-by: Qiang Yu <yuq825@gmail.com> (v1)
			
			
This commit is contained in:
		
							parent
							
								
									c8f005684c
								
							
						
					
					
						commit
						5d5a179d3e
					
				
					 2 changed files with 98 additions and 0 deletions
				
			
		|  | @ -1367,3 +1367,96 @@ drm_gem_unlock_reservations(struct drm_gem_object **objs, int count, | ||||||
| 	ww_acquire_fini(acquire_ctx); | 	ww_acquire_fini(acquire_ctx); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(drm_gem_unlock_reservations); | EXPORT_SYMBOL(drm_gem_unlock_reservations); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * drm_gem_fence_array_add - Adds the fence to an array of fences to be | ||||||
|  |  * waited on, deduplicating fences from the same context. | ||||||
|  |  * | ||||||
|  |  * @fence_array array of dma_fence * for the job to block on. | ||||||
|  |  * @fence the dma_fence to add to the list of dependencies. | ||||||
|  |  * | ||||||
|  |  * Returns: | ||||||
|  |  * 0 on success, or an error on failing to expand the array. | ||||||
|  |  */ | ||||||
|  | int drm_gem_fence_array_add(struct xarray *fence_array, | ||||||
|  | 			    struct dma_fence *fence) | ||||||
|  | { | ||||||
|  | 	struct dma_fence *entry; | ||||||
|  | 	unsigned long index; | ||||||
|  | 	u32 id = 0; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	if (!fence) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	/* Deduplicate if we already depend on a fence from the same context.
 | ||||||
|  | 	 * This lets the size of the array of deps scale with the number of | ||||||
|  | 	 * engines involved, rather than the number of BOs. | ||||||
|  | 	 */ | ||||||
|  | 	xa_for_each(fence_array, index, entry) { | ||||||
|  | 		if (entry->context != fence->context) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		if (dma_fence_is_later(fence, entry)) { | ||||||
|  | 			dma_fence_put(entry); | ||||||
|  | 			xa_store(fence_array, index, fence, GFP_KERNEL); | ||||||
|  | 		} else { | ||||||
|  | 			dma_fence_put(fence); | ||||||
|  | 		} | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret = xa_alloc(fence_array, &id, fence, xa_limit_32b, GFP_KERNEL); | ||||||
|  | 	if (ret != 0) | ||||||
|  | 		dma_fence_put(fence); | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(drm_gem_fence_array_add); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * drm_gem_fence_array_add_implicit - Adds the implicit dependencies tracked | ||||||
|  |  * in the GEM object's reservation object to an array of dma_fences for use in | ||||||
|  |  * scheduling a rendering job. | ||||||
|  |  * | ||||||
|  |  * This should be called after drm_gem_lock_reservations() on your array of | ||||||
|  |  * GEM objects used in the job but before updating the reservations with your | ||||||
|  |  * own fences. | ||||||
|  |  * | ||||||
|  |  * @fence_array array of dma_fence * for the job to block on. | ||||||
|  |  * @obj the gem object to add new dependencies from. | ||||||
|  |  * @write whether the job might write the object (so we need to depend on | ||||||
|  |  * shared fences in the reservation object). | ||||||
|  |  */ | ||||||
|  | int drm_gem_fence_array_add_implicit(struct xarray *fence_array, | ||||||
|  | 				     struct drm_gem_object *obj, | ||||||
|  | 				     bool write) | ||||||
|  | { | ||||||
|  | 	int ret; | ||||||
|  | 	struct dma_fence **fences; | ||||||
|  | 	unsigned int i, fence_count; | ||||||
|  | 
 | ||||||
|  | 	if (!write) { | ||||||
|  | 		struct dma_fence *fence = | ||||||
|  | 			reservation_object_get_excl_rcu(obj->resv); | ||||||
|  | 
 | ||||||
|  | 		return drm_gem_fence_array_add(fence_array, fence); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret = reservation_object_get_fences_rcu(obj->resv, NULL, | ||||||
|  | 						&fence_count, &fences); | ||||||
|  | 	if (ret || !fence_count) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < fence_count; i++) { | ||||||
|  | 		ret = drm_gem_fence_array_add(fence_array, fences[i]); | ||||||
|  | 		if (ret) | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (; i < fence_count; i++) | ||||||
|  | 		dma_fence_put(fences[i]); | ||||||
|  | 	kfree(fences); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(drm_gem_fence_array_add_implicit); | ||||||
|  |  | ||||||
|  | @ -390,6 +390,11 @@ int drm_gem_lock_reservations(struct drm_gem_object **objs, int count, | ||||||
| 			      struct ww_acquire_ctx *acquire_ctx); | 			      struct ww_acquire_ctx *acquire_ctx); | ||||||
| void drm_gem_unlock_reservations(struct drm_gem_object **objs, int count, | void drm_gem_unlock_reservations(struct drm_gem_object **objs, int count, | ||||||
| 				 struct ww_acquire_ctx *acquire_ctx); | 				 struct ww_acquire_ctx *acquire_ctx); | ||||||
|  | int drm_gem_fence_array_add(struct xarray *fence_array, | ||||||
|  | 			    struct dma_fence *fence); | ||||||
|  | int drm_gem_fence_array_add_implicit(struct xarray *fence_array, | ||||||
|  | 				     struct drm_gem_object *obj, | ||||||
|  | 				     bool write); | ||||||
| int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, | int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, | ||||||
| 			    u32 handle, u64 *offset); | 			    u32 handle, u64 *offset); | ||||||
| int drm_gem_dumb_destroy(struct drm_file *file, | int drm_gem_dumb_destroy(struct drm_file *file, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Eric Anholt
						Eric Anholt