[PATCH v4 1/2] dma-fence: Add helper to sort and deduplicate dma_fence arrays

Christian König christian.koenig at amd.com
Fri May 2 07:55:03 UTC 2025


On 4/30/25 18:05, Arvind Yadav wrote:
> Export a new helper function `dma_fence_dedup_array()` that sorts
> an array of dma_fence pointers by context, then deduplicates the array
> by retaining only the most recent fence per context.
> 
> This utility is useful when merging or optimizing sets of fences where
> redundant entries from the same context can be pruned. The operation is
> performed in-place and releases references to dropped fences using
> dma_fence_put().
> 
> v2: - Export this code from dma-fence-unwrap.c(by Christian).
> v3: - To split this in a dma_buf patch and amd userq patch(by Sunil).
>     - No need to add a new function just re-use existing(by Christian).
> v4: - Export dma_fence_dedub_array and use it(by Christian).
> 
> Cc: Alex Deucher <alexander.deucher at amd.com>
> Cc: Christian Koenig <christian.koenig at amd.com>
> Cc: Sunil Khatri <sunil.khatri at amd.com>
> Cc: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam at amd.com>
> Signed-off-by: Arvind Yadav <Arvind.Yadav at amd.com>

Reviewed-by: Christian König <christian.koenig at amd.com>

> ---
>  drivers/dma-buf/dma-fence-unwrap.c | 51 ++++++++++++++++++++++--------
>  include/linux/dma-fence-unwrap.h   |  2 ++
>  2 files changed, 39 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c
> index 2a059ac0ed27..a495d8a6c2e3 100644
> --- a/drivers/dma-buf/dma-fence-unwrap.c
> +++ b/drivers/dma-buf/dma-fence-unwrap.c
> @@ -79,6 +79,41 @@ static int fence_cmp(const void *_a, const void *_b)
>  	return 0;
>  }
>  
> +/**
> + * dma_fence_dedup_array - Sort and deduplicate an array of dma_fence pointers
> + * @fences:     Array of dma_fence pointers to be deduplicated
> + * @num_fences: Number of entries in the @fences array
> + *
> + * Sorts the input array by context, then removes duplicate
> + * fences with the same context, keeping only the most recent one.
> + *
> + * The array is modified in-place and unreferenced duplicate fences are released
> + * via dma_fence_put(). The function returns the new number of fences after
> + * deduplication.
> + *
> + * Return: Number of unique fences remaining in the array.
> + */
> +int dma_fence_dedup_array(struct dma_fence **fences, int num_fences)
> +{
> +	int i, j;
> +
> +	sort(fences, num_fences, sizeof(*fences), fence_cmp, NULL);
> +
> +	/*
> +	 * Only keep the most recent fence for each context.
> +	 */
> +	j = 0;
> +	for (i = 1; i < num_fences; i++) {
> +		if (fences[i]->context == fences[j]->context)
> +			dma_fence_put(fences[i]);
> +		else
> +			fences[++j] = fences[i];
> +	}
> +
> +	return ++j;
> +}
> +EXPORT_SYMBOL_GPL(dma_fence_dedup_array);
> +
>  /* Implementation for the dma_fence_merge() marco, don't use directly */
>  struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
>  					   struct dma_fence **fences,
> @@ -87,7 +122,7 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
>  	struct dma_fence *tmp, *unsignaled = NULL, **array;
>  	struct dma_fence_array *result;
>  	ktime_t timestamp;
> -	int i, j, count;
> +	int i, count;
>  
>  	count = 0;
>  	timestamp = ns_to_ktime(0);
> @@ -141,19 +176,7 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
>  	if (count == 0 || count == 1)
>  		goto return_fastpath;
>  
> -	sort(array, count, sizeof(*array), fence_cmp, NULL);
> -
> -	/*
> -	 * Only keep the most recent fence for each context.
> -	 */
> -	j = 0;
> -	for (i = 1; i < count; i++) {
> -		if (array[i]->context == array[j]->context)
> -			dma_fence_put(array[i]);
> -		else
> -			array[++j] = array[i];
> -	}
> -	count = ++j;
> +	count = dma_fence_dedup_array(array, count);
>  
>  	if (count > 1) {
>  		result = dma_fence_array_create(count, array,
> diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h
> index 66b1e56fbb81..62df222fe0f1 100644
> --- a/include/linux/dma-fence-unwrap.h
> +++ b/include/linux/dma-fence-unwrap.h
> @@ -52,6 +52,8 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
>  					   struct dma_fence **fences,
>  					   struct dma_fence_unwrap *cursors);
>  
> +int dma_fence_dedup_array(struct dma_fence **array, int num_fences);
> +
>  /**
>   * dma_fence_unwrap_merge - unwrap and merge fences
>   *



More information about the amd-gfx mailing list