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

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
...@@ -423,6 +423,57 @@ struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor) ...@@ -423,6 +423,57 @@ struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor)
} }
EXPORT_SYMBOL(dma_resv_iter_next_unlocked); 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. * dma_resv_copy_fences - Copy all fences from src to dst.
* @dst: the destination reservation object * @dst: the destination reservation object
......
...@@ -179,6 +179,8 @@ struct dma_resv_iter { ...@@ -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_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_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 * 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) ...@@ -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); \ for (fence = dma_resv_iter_first_unlocked(cursor); \
fence; fence = dma_resv_iter_next_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_held(obj) lockdep_is_held(&(obj)->lock.base)
#define dma_resv_assert_held(obj) lockdep_assert_held(&(obj)->lock.base) #define dma_resv_assert_held(obj) lockdep_assert_held(&(obj)->lock.base)
......
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