dma-buf: make returning the exclusive fence optional

Change reservation_object_get_fences_rcu to make the exclusive fence
pointer optional.

If not specified the exclusive fence is put into the fence array as
well.

This is helpful for a couple of cases where we need all fences in a
single array.

Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180110125341.3618-1-christian.koenig@amd.com
This commit is contained in:
Christian König 2018-01-10 13:53:41 +01:00 committed by Alex Deucher
parent c60c4af36d
commit a35f2f34b5
1 changed files with 22 additions and 9 deletions

View File

@ -374,8 +374,9 @@ EXPORT_SYMBOL(reservation_object_copy_fences);
* @pshared: the array of shared fence ptrs returned (array is krealloc'd to
* the required size, and must be freed by caller)
*
* RETURNS
* Zero or -errno
* 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
* shared fences as well. Returns either zero or -ENOMEM.
*/
int reservation_object_get_fences_rcu(struct reservation_object *obj,
struct dma_fence **pfence_excl,
@ -389,8 +390,8 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj,
do {
struct reservation_object_list *fobj;
unsigned seq;
unsigned int i;
unsigned int i, seq;
size_t sz = 0;
shared_count = i = 0;
@ -402,9 +403,14 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj,
goto unlock;
fobj = rcu_dereference(obj->fence);
if (fobj) {
if (fobj)
sz += sizeof(*shared) * fobj->shared_max;
if (!pfence_excl && fence_excl)
sz += sizeof(*shared);
if (sz) {
struct dma_fence **nshared;
size_t sz = sizeof(*shared) * fobj->shared_max;
nshared = krealloc(shared, sz,
GFP_NOWAIT | __GFP_NOWARN);
@ -420,13 +426,19 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj,
break;
}
shared = nshared;
shared_count = fobj->shared_count;
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 (!pfence_excl && fence_excl) {
shared[i] = fence_excl;
fence_excl = NULL;
++i;
++shared_count;
}
}
if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) {
@ -448,7 +460,8 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj,
*pshared_count = shared_count;
*pshared = shared;
*pfence_excl = fence_excl;
if (pfence_excl)
*pfence_excl = fence_excl;
return ret;
}