mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-04 04:44:37 +08:00
dma-buf: add dma_resv_get_singleton v2
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@amd.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20220321135856.1331-3-christian.koenig@amd.com
This commit is contained in:
parent
d791aec9ff
commit
92cedee6a6
@ -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>
|
||||
@ -636,6 +637,59 @@ 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.
|
||||
*
|
||||
* 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);
|
||||
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.
|
||||
|
@ -437,6 +437,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);
|
||||
|
Loading…
Reference in New Issue
Block a user