diff options
author | Christian König <christian.koenig@amd.com> | 2019-08-06 14:19:33 +0200 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2019-08-10 12:49:06 +0200 |
commit | 67c97fb79a7f8621d4514275691d75f5ff158c46 (patch) | |
tree | f28ca7b330a682a54504ea8857f41d468dbd58db /include | |
parent | dma-buf: make dma_fence structure a bit smaller v2 (diff) | |
download | linux-67c97fb79a7f8621d4514275691d75f5ff158c46.tar.xz linux-67c97fb79a7f8621d4514275691d75f5ff158c46.zip |
dma-buf: add reservation_object_fences helper
Add a new helper to get a consistent set of pointers from the reservation
object. While at it group all access helpers together in the header file.
v2: correctly return shared_count as well
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/322378/?series=64837&rev=1
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/reservation.h | 115 |
1 files changed, 70 insertions, 45 deletions
diff --git a/include/linux/reservation.h b/include/linux/reservation.h index 56b782fec49b..c6c8c93785c4 100644 --- a/include/linux/reservation.h +++ b/include/linux/reservation.h @@ -82,6 +82,25 @@ struct reservation_object { lockdep_assert_held(&(obj)->lock.base) /** + * reservation_object_get_excl - get the reservation object's + * exclusive fence, with update-side lock held + * @obj: the reservation object + * + * Returns the exclusive fence (if any). Does NOT take a + * reference. Writers must hold obj->lock, readers may only + * hold a RCU read side lock. + * + * RETURNS + * The exclusive fence or NULL + */ +static inline struct dma_fence * +reservation_object_get_excl(struct reservation_object *obj) +{ + return rcu_dereference_protected(obj->fence_excl, + reservation_object_held(obj)); +} + +/** * reservation_object_get_list - get the reservation object's * shared fence list, with update-side lock held * @obj: the reservation object @@ -97,6 +116,57 @@ reservation_object_get_list(struct reservation_object *obj) } /** + * reservation_object_fences - read consistent fence pointers + * @obj: reservation object where we get the fences from + * @excl: pointer for the exclusive fence + * @list: pointer for the shared fence list + * + * Make sure we have a consisten exclusive fence and shared fence list. + * Must be called with rcu read side lock held. + */ +static inline void +reservation_object_fences(struct reservation_object *obj, + struct dma_fence **excl, + struct reservation_object_list **list, + u32 *shared_count) +{ + unsigned int seq; + + do { + seq = read_seqcount_begin(&obj->seq); + *excl = rcu_dereference(obj->fence_excl); + *list = rcu_dereference(obj->fence); + *shared_count = *list ? (*list)->shared_count : 0; + } while (read_seqcount_retry(&obj->seq, seq)); +} + +/** + * reservation_object_get_excl_rcu - get the reservation object's + * exclusive fence, without lock held. + * @obj: the reservation object + * + * If there is an exclusive fence, this atomically increments it's + * reference count and returns it. + * + * RETURNS + * The exclusive fence or NULL if none + */ +static inline struct dma_fence * +reservation_object_get_excl_rcu(struct reservation_object *obj) +{ + struct dma_fence *fence; + + if (!rcu_access_pointer(obj->fence_excl)) + return NULL; + + rcu_read_lock(); + fence = dma_fence_get_rcu_safe(&obj->fence_excl); + rcu_read_unlock(); + + return fence; +} + +/** * reservation_object_lock - lock the reservation object * @obj: the reservation object * @ctx: the locking context @@ -239,51 +309,6 @@ reservation_object_unlock(struct reservation_object *obj) ww_mutex_unlock(&obj->lock); } -/** - * reservation_object_get_excl - get the reservation object's - * exclusive fence, with update-side lock held - * @obj: the reservation object - * - * Returns the exclusive fence (if any). Does NOT take a - * reference. Writers must hold obj->lock, readers may only - * hold a RCU read side lock. - * - * RETURNS - * The exclusive fence or NULL - */ -static inline struct dma_fence * -reservation_object_get_excl(struct reservation_object *obj) -{ - return rcu_dereference_protected(obj->fence_excl, - reservation_object_held(obj)); -} - -/** - * reservation_object_get_excl_rcu - get the reservation object's - * exclusive fence, without lock held. - * @obj: the reservation object - * - * If there is an exclusive fence, this atomically increments it's - * reference count and returns it. - * - * RETURNS - * The exclusive fence or NULL if none - */ -static inline struct dma_fence * -reservation_object_get_excl_rcu(struct reservation_object *obj) -{ - struct dma_fence *fence; - - if (!rcu_access_pointer(obj->fence_excl)) - return NULL; - - rcu_read_lock(); - fence = dma_fence_get_rcu_safe(&obj->fence_excl); - rcu_read_unlock(); - - return fence; -} - void reservation_object_init(struct reservation_object *obj); void reservation_object_fini(struct reservation_object *obj); int reservation_object_reserve_shared(struct reservation_object *obj, |