summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2019-08-06 14:19:33 +0200
committerChristian König <christian.koenig@amd.com>2019-08-10 12:49:06 +0200
commit67c97fb79a7f8621d4514275691d75f5ff158c46 (patch)
treef28ca7b330a682a54504ea8857f41d468dbd58db /include/linux
parent0e2f733addbf7702065cc18d38b67a1284d0c2be (diff)
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/linux')
-rw-r--r--include/linux/reservation.h115
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,