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 <[email protected]>
> Cc: Christian Koenig <[email protected]>
> Cc: Sunil Khatri <[email protected]>
> Cc: Arunpravin Paneer Selvam <[email protected]>
> Signed-off-by: Arvind Yadav <[email protected]>

Reviewed-by: Christian König <[email protected]>

> ---
>  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
>   *

Reply via email to