--- drivers/dma-buf/reservation.c | 58 +++++++++++++++++++++++++++++++++++++++++++ include/linux/reservation.h | 4 +++ 2 files changed, 62 insertions(+) diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c index 3c9ab53be2b9..0f254d0d9bec 100644 --- a/drivers/dma-buf/reservation.c +++ b/drivers/dma-buf/reservation.c @@ -133,6 +133,64 @@ void reservation_object_add_excl_fence(struct reservation_object *obj, EXPORT_SYMBOL(reservation_object_add_excl_fence); /** + * reservation_object_get_fences_locked - Get an object's shared and exclusive + * fences + * @obj: the reservation object + * @pfence_excl: the returned exclusive fence (or NULL) + * @pshared_count: the number of shared fences returned + * @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 + */ +int reservation_object_get_fences_locked(struct reservation_object *obj, + struct dma_fence **pfence_excl, + unsigned *pshared_count, + struct dma_fence ***pshared) +{ + struct dma_fence **shared = NULL; + unsigned int count = 0; + struct radix_tree_iter iter; + void **slot; + + radix_tree_for_each_slot(slot, &obj->shared, &iter, 0) { + struct dma_fence *fence = radix_tree_deref_slot(slot); + + if (dma_fence_is_signaled(fence)) { + radix_tree_delete(&obj->shared, iter.index); + continue; + } + + if ((count & -count) == count) { + struct dma_fence **nshared; + unsigned int sz; + + sz = count ? 2*count : 1; + nshared = krealloc(shared, + sz * sizeof(*shared), + GFP_TEMPORARY); + if (!nshared) { + while (count--) + dma_fence_put(shared[count]); + kfree(shared); + return -ENOMEM; + } + + shared = nshared; + } + + shared[count++] = dma_fence_get(fence); + } + + *pshared_count = count; + *pshared = shared; + *pfence_excl = dma_fence_get(rcu_dereference(obj->excl)); + return 0; +} +EXPORT_SYMBOL_GPL(reservation_object_get_fences_locked); + +/** * reservation_object_get_fences_rcu - Get an object's shared and exclusive * fences without update side lock held * @obj: the reservation object diff --git a/include/linux/reservation.h b/include/linux/reservation.h index 697ec52427ca..4f39942906e2 100644 --- a/include/linux/reservation.h +++ b/include/linux/reservation.h @@ -161,6 +161,10 @@ void reservation_object_add_shared_fence(struct reservation_object *obj, void reservation_object_add_excl_fence(struct reservation_object *obj, struct dma_fence *fence); +int reservation_object_get_fences_locked(struct reservation_object *obj, + struct dma_fence **pfence_excl, + unsigned *pshared_count, + struct dma_fence ***pshared); int reservation_object_get_fences_rcu(struct reservation_object *obj, struct dma_fence **pfence_excl, unsigned *pshared_count, -- 2.10.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx