mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
dma-buf: use new iterator in dma_resv_get_fences v3
This makes the function much simpler since the complex retry logic is now handled elsewhere. v2: use sizeof(void*) instead v3: fix rebase bug 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/20211005113742.1101-6-christian.koenig@amd.com
This commit is contained in:
parent
96601e8a47
commit
d3c80698c9
@ -489,99 +489,61 @@ EXPORT_SYMBOL(dma_resv_copy_fences);
|
|||||||
* dma_resv_get_fences - Get an object's shared and exclusive
|
* dma_resv_get_fences - Get an object's shared and exclusive
|
||||||
* fences without update side lock held
|
* fences without update side lock held
|
||||||
* @obj: the reservation object
|
* @obj: the reservation object
|
||||||
* @pfence_excl: the returned exclusive fence (or NULL)
|
* @fence_excl: the returned exclusive fence (or NULL)
|
||||||
* @pshared_count: the number of shared fences returned
|
* @shared_count: the number of shared fences returned
|
||||||
* @pshared: the array of shared fence ptrs returned (array is krealloc'd to
|
* @shared: the array of shared fence ptrs returned (array is krealloc'd to
|
||||||
* the required size, and must be freed by caller)
|
* the required size, and must be freed by caller)
|
||||||
*
|
*
|
||||||
* Retrieve all fences from the reservation object. If the pointer for the
|
* Retrieve all fences from the reservation object. If the pointer for the
|
||||||
* exclusive fence is not specified the fence is put into the array of the
|
* exclusive fence is not specified the fence is put into the array of the
|
||||||
* shared fences as well. Returns either zero or -ENOMEM.
|
* shared fences as well. Returns either zero or -ENOMEM.
|
||||||
*/
|
*/
|
||||||
int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **pfence_excl,
|
int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **fence_excl,
|
||||||
unsigned int *pshared_count,
|
unsigned int *shared_count, struct dma_fence ***shared)
|
||||||
struct dma_fence ***pshared)
|
|
||||||
{
|
{
|
||||||
struct dma_fence **shared = NULL;
|
struct dma_resv_iter cursor;
|
||||||
struct dma_fence *fence_excl;
|
struct dma_fence *fence;
|
||||||
unsigned int shared_count;
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
do {
|
*shared_count = 0;
|
||||||
struct dma_resv_list *fobj;
|
*shared = NULL;
|
||||||
unsigned int i, seq;
|
|
||||||
size_t sz = 0;
|
|
||||||
|
|
||||||
shared_count = i = 0;
|
if (fence_excl)
|
||||||
|
*fence_excl = NULL;
|
||||||
|
|
||||||
rcu_read_lock();
|
dma_resv_iter_begin(&cursor, obj, true);
|
||||||
seq = read_seqcount_begin(&obj->seq);
|
dma_resv_for_each_fence_unlocked(&cursor, fence) {
|
||||||
|
|
||||||
fence_excl = dma_resv_excl_fence(obj);
|
if (dma_resv_iter_is_restarted(&cursor)) {
|
||||||
if (fence_excl && !dma_fence_get_rcu(fence_excl))
|
unsigned int count;
|
||||||
goto unlock;
|
|
||||||
|
|
||||||
fobj = dma_resv_shared_list(obj);
|
while (*shared_count)
|
||||||
if (fobj)
|
dma_fence_put((*shared)[--(*shared_count)]);
|
||||||
sz += sizeof(*shared) * fobj->shared_max;
|
|
||||||
|
|
||||||
if (!pfence_excl && fence_excl)
|
if (fence_excl)
|
||||||
sz += sizeof(*shared);
|
dma_fence_put(*fence_excl);
|
||||||
|
|
||||||
if (sz) {
|
count = cursor.fences ? cursor.fences->shared_count : 0;
|
||||||
struct dma_fence **nshared;
|
count += fence_excl ? 0 : 1;
|
||||||
|
|
||||||
nshared = krealloc(shared, sz,
|
/* Eventually re-allocate the array */
|
||||||
GFP_NOWAIT | __GFP_NOWARN);
|
*shared = krealloc_array(*shared, count,
|
||||||
if (!nshared) {
|
sizeof(void *),
|
||||||
rcu_read_unlock();
|
GFP_KERNEL);
|
||||||
|
if (count && !*shared) {
|
||||||
dma_fence_put(fence_excl);
|
dma_resv_iter_end(&cursor);
|
||||||
fence_excl = NULL;
|
return -ENOMEM;
|
||||||
|
|
||||||
nshared = krealloc(shared, sz, GFP_KERNEL);
|
|
||||||
if (nshared) {
|
|
||||||
shared = nshared;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = -ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
shared = nshared;
|
|
||||||
shared_count = fobj ? fobj->shared_count : 0;
|
|
||||||
for (i = 0; i < shared_count; ++i) {
|
|
||||||
shared[i] = rcu_dereference(fobj->shared[i]);
|
|
||||||
if (!dma_fence_get_rcu(shared[i]))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) {
|
dma_fence_get(fence);
|
||||||
while (i--)
|
if (dma_resv_iter_is_exclusive(&cursor) && fence_excl)
|
||||||
dma_fence_put(shared[i]);
|
*fence_excl = fence;
|
||||||
dma_fence_put(fence_excl);
|
else
|
||||||
goto unlock;
|
(*shared)[(*shared_count)++] = fence;
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
unlock:
|
|
||||||
rcu_read_unlock();
|
|
||||||
} while (ret);
|
|
||||||
|
|
||||||
if (pfence_excl)
|
|
||||||
*pfence_excl = fence_excl;
|
|
||||||
else if (fence_excl)
|
|
||||||
shared[shared_count++] = fence_excl;
|
|
||||||
|
|
||||||
if (!shared_count) {
|
|
||||||
kfree(shared);
|
|
||||||
shared = NULL;
|
|
||||||
}
|
}
|
||||||
|
dma_resv_iter_end(&cursor);
|
||||||
|
|
||||||
*pshared_count = shared_count;
|
return 0;
|
||||||
*pshared = shared;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dma_resv_get_fences);
|
EXPORT_SYMBOL_GPL(dma_resv_get_fences);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user