Commit 5baaac31 authored by Christian König's avatar Christian König
Browse files

dma-buf: add dma_resv_for_each_fence v3



A simpler version of the iterator to be used when the dma_resv object is
locked.

v2: fix index check here as well
v3: minor coding improvement, some documentation cleanup

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211006123609.2026-1-christian.koenig@amd.com
parent a0a33067
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -423,6 +423,57 @@ struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor)
}
EXPORT_SYMBOL(dma_resv_iter_next_unlocked);

/**
 * dma_resv_iter_first - first fence from a locked dma_resv object
 * @cursor: cursor to record the current position
 *
 * Return the first fence in the dma_resv object while holding the
 * &dma_resv.lock.
 */
struct dma_fence *dma_resv_iter_first(struct dma_resv_iter *cursor)
{
	struct dma_fence *fence;

	dma_resv_assert_held(cursor->obj);

	cursor->index = 0;
	if (cursor->all_fences)
		cursor->fences = dma_resv_shared_list(cursor->obj);
	else
		cursor->fences = NULL;

	fence = dma_resv_excl_fence(cursor->obj);
	if (!fence)
		fence = dma_resv_iter_next(cursor);

	cursor->is_restarted = true;
	return fence;
}
EXPORT_SYMBOL_GPL(dma_resv_iter_first);

/**
 * dma_resv_iter_next - next fence from a locked dma_resv object
 * @cursor: cursor to record the current position
 *
 * Return the next fences from the dma_resv object while holding the
 * &dma_resv.lock.
 */
struct dma_fence *dma_resv_iter_next(struct dma_resv_iter *cursor)
{
	unsigned int idx;

	dma_resv_assert_held(cursor->obj);

	cursor->is_restarted = false;
	if (!cursor->fences || cursor->index >= cursor->fences->shared_count)
		return NULL;

	idx = cursor->index++;
	return rcu_dereference_protected(cursor->fences->shared[idx],
					 dma_resv_held(cursor->obj));
}
EXPORT_SYMBOL_GPL(dma_resv_iter_next);

/**
 * dma_resv_copy_fences - Copy all fences from src to dst.
 * @dst: the destination reservation object
+20 −0
Original line number Diff line number Diff line
@@ -179,6 +179,8 @@ struct dma_resv_iter {

struct dma_fence *dma_resv_iter_first_unlocked(struct dma_resv_iter *cursor);
struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor);
struct dma_fence *dma_resv_iter_first(struct dma_resv_iter *cursor);
struct dma_fence *dma_resv_iter_next(struct dma_resv_iter *cursor);

/**
 * dma_resv_iter_begin - initialize a dma_resv_iter object
@@ -244,6 +246,24 @@ static inline bool dma_resv_iter_is_restarted(struct dma_resv_iter *cursor)
	for (fence = dma_resv_iter_first_unlocked(cursor);		\
	     fence; fence = dma_resv_iter_next_unlocked(cursor))

/**
 * dma_resv_for_each_fence - fence iterator
 * @cursor: a struct dma_resv_iter pointer
 * @obj: a dma_resv object pointer
 * @all_fences: true if all fences should be returned
 * @fence: the current fence
 *
 * Iterate over the fences in a struct dma_resv object while holding the
 * &dma_resv.lock. @all_fences controls if the shared fences are returned as
 * well. The cursor initialisation is part of the iterator and the fence stays
 * valid as long as the lock is held and so no extra reference to the fence is
 * taken.
 */
#define dma_resv_for_each_fence(cursor, obj, all_fences, fence)	\
	for (dma_resv_iter_begin(cursor, obj, all_fences),	\
	     fence = dma_resv_iter_first(cursor); fence;	\
	     fence = dma_resv_iter_next(cursor))

#define dma_resv_held(obj) lockdep_is_held(&(obj)->lock.base)
#define dma_resv_assert_held(obj) lockdep_assert_held(&(obj)->lock.base)