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

Khatri, Sunil Sunil.Khatri at amd.com
Fri May 2 12:26:01 UTC 2025


[AMD Official Use Only - AMD Internal Distribution Only]

Reviewed-by: Sunil Khatri <sunil.khatri at amd.com>

-----Original Message-----
From: Koenig, Christian <Christian.Koenig at amd.com>
Sent: Friday, May 2, 2025 1:25 PM
To: Yadav, Arvind <Arvind.Yadav at amd.com>; Deucher, Alexander <Alexander.Deucher at amd.com>; Khatri, Sunil <Sunil.Khatri at amd.com>; Paneer Selvam, Arunpravin <Arunpravin.PaneerSelvam at amd.com>
Cc: amd-gfx at lists.freedesktop.org
Subject: Re: [PATCH v4 1/2] dma-fence: Add helper to sort and deduplicate dma_fence arrays

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