Commit d3c80698 authored by Christian König's avatar Christian König

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: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20211005113742.1101-6-christian.koenig@amd.com
parent 96601e8a
...@@ -489,99 +489,61 @@ EXPORT_SYMBOL(dma_resv_copy_fences); ...@@ -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 {
struct dma_resv_list *fobj;
unsigned int i, seq;
size_t sz = 0;
shared_count = i = 0;
rcu_read_lock();
seq = read_seqcount_begin(&obj->seq);
fence_excl = dma_resv_excl_fence(obj); *shared_count = 0;
if (fence_excl && !dma_fence_get_rcu(fence_excl)) *shared = NULL;
goto unlock;
fobj = dma_resv_shared_list(obj); if (fence_excl)
if (fobj) *fence_excl = NULL;
sz += sizeof(*shared) * fobj->shared_max;
if (!pfence_excl && fence_excl) dma_resv_iter_begin(&cursor, obj, true);
sz += sizeof(*shared); dma_resv_for_each_fence_unlocked(&cursor, fence) {
if (sz) { if (dma_resv_iter_is_restarted(&cursor)) {
struct dma_fence **nshared; unsigned int count;
nshared = krealloc(shared, sz, while (*shared_count)
GFP_NOWAIT | __GFP_NOWARN); dma_fence_put((*shared)[--(*shared_count)]);
if (!nshared) {
rcu_read_unlock();
dma_fence_put(fence_excl); if (fence_excl)
fence_excl = NULL; dma_fence_put(*fence_excl);
nshared = krealloc(shared, sz, GFP_KERNEL); count = cursor.fences ? cursor.fences->shared_count : 0;
if (nshared) { count += fence_excl ? 0 : 1;
shared = nshared;
continue;
}
ret = -ENOMEM; /* Eventually re-allocate the array */
break; *shared = krealloc_array(*shared, count,
} sizeof(void *),
shared = nshared; GFP_KERNEL);
shared_count = fobj ? fobj->shared_count : 0; if (count && !*shared) {
for (i = 0; i < shared_count; ++i) { dma_resv_iter_end(&cursor);
shared[i] = rcu_dereference(fobj->shared[i]); return -ENOMEM;
if (!dma_fence_get_rcu(shared[i]))
break;
}
} }
if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) {
while (i--)
dma_fence_put(shared[i]);
dma_fence_put(fence_excl);
goto unlock;
} }
ret = 0; dma_fence_get(fence);
unlock: if (dma_resv_iter_is_exclusive(&cursor) && fence_excl)
rcu_read_unlock(); *fence_excl = fence;
} while (ret); else
(*shared)[(*shared_count)++] = fence;
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment