On Fri, Apr 01, 2022 at 10:21:22AM +0200, Christian König wrote: > Daniel any more comments on this one here? > > It's the prerequisite to a bunch of other patches and I would like to get it > out of my feet. Apologies for the miss, I thought I've r-b stamped this one already. > > Thanks, > Christian. > > Am 21.03.22 um 14:58 schrieb Christian König: > > Add a function to simplify getting a single fence for all the fences in > > the dma_resv object. > > > > v2: fix ref leak in error handling > > > > Signed-off-by: Christian König <christian.koenig@xxxxxxx> > > --- > > drivers/dma-buf/dma-resv.c | 52 ++++++++++++++++++++++++++++++++++++++ > > include/linux/dma-resv.h | 2 ++ > > 2 files changed, 54 insertions(+) > > > > diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c > > index 5001e9b4420a..c09fd8da0c85 100644 > > --- a/drivers/dma-buf/dma-resv.c > > +++ b/drivers/dma-buf/dma-resv.c > > @@ -34,6 +34,7 @@ > > */ > > #include <linux/dma-resv.h> > > +#include <linux/dma-fence-array.h> > > #include <linux/export.h> > > #include <linux/mm.h> > > #include <linux/sched/mm.h> > > @@ -650,6 +651,57 @@ int dma_resv_get_fences(struct dma_resv *obj, bool write, > > } > > EXPORT_SYMBOL_GPL(dma_resv_get_fences); > > +/** > > + * dma_resv_get_singleton - Get a single fence for all the fences > > + * @obj: the reservation object > > + * @write: true if we should return all fences > > + * @fence: the resulting fence > > + * > > + * Get a single fence representing all the fences inside the resv object. > > + * Returns either 0 for success or -ENOMEM. > > + * > > + * Warning: This can't be used like this when adding the fence back to the resv > > + * object since that can lead to stack corruption when finalizing the > > + * dma_fence_array. Please add the standard boilerplate here: Returns 0 on success and negative error values on failure. > > + */ > > +int dma_resv_get_singleton(struct dma_resv *obj, bool write, > > + struct dma_fence **fence) > > +{ > > + struct dma_fence_array *array; > > + struct dma_fence **fences; > > + unsigned count; > > + int r; > > + > > + r = dma_resv_get_fences(obj, write, &count, &fences); Deep down in here we already have the dma_resv_assert_held, so I'm happy. Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx> > > + if (r) > > + return r; > > + > > + if (count == 0) { > > + *fence = NULL; > > + return 0; > > + } > > + > > + if (count == 1) { > > + *fence = fences[0]; > > + kfree(fences); > > + return 0; > > + } > > + > > + array = dma_fence_array_create(count, fences, > > + dma_fence_context_alloc(1), > > + 1, false); > > + if (!array) { > > + while (count--) > > + dma_fence_put(fences[count]); > > + kfree(fences); > > + return -ENOMEM; > > + } > > + > > + *fence = &array->base; > > + return 0; > > +} > > +EXPORT_SYMBOL_GPL(dma_resv_get_singleton); > > + > > /** > > * dma_resv_wait_timeout - Wait on reservation's objects > > * shared and/or exclusive fences. > > diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h > > index 202cc65d0621..08512c1e215d 100644 > > --- a/include/linux/dma-resv.h > > +++ b/include/linux/dma-resv.h > > @@ -449,6 +449,8 @@ void dma_resv_replace_fences(struct dma_resv *obj, uint64_t context, > > void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence); > > int dma_resv_get_fences(struct dma_resv *obj, bool write, > > unsigned int *num_fences, struct dma_fence ***fences); > > +int dma_resv_get_singleton(struct dma_resv *obj, bool write, > > + struct dma_fence **fence); > > int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src); > > long dma_resv_wait_timeout(struct dma_resv *obj, bool wait_all, bool intr, > > unsigned long timeout); > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch