[AMD Official Use Only - AMD Internal Distribution Only] Reviewed-by: Sunil Khatri <sunil.kha...@amd.com>
-----Original Message----- From: Koenig, Christian <christian.koe...@amd.com> Sent: Friday, May 2, 2025 1:25 PM To: Yadav, Arvind <arvind.ya...@amd.com>; Deucher, Alexander <alexander.deuc...@amd.com>; Khatri, Sunil <sunil.kha...@amd.com>; Paneer Selvam, Arunpravin <arunpravin.paneersel...@amd.com> Cc: amd-gfx@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.deuc...@amd.com> > Cc: Christian Koenig <christian.koe...@amd.com> > Cc: Sunil Khatri <sunil.kha...@amd.com> > Cc: Arunpravin Paneer Selvam <arunpravin.paneersel...@amd.com> > Signed-off-by: Arvind Yadav <arvind.ya...@amd.com> Reviewed-by: Christian König <christian.koe...@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 > *