aboutsummaryrefslogtreecommitdiff
path: root/drivers/dma-buf
diff options
context:
space:
mode:
authorChristian König2021-09-24 10:55:45 +0200
committerChristian König2022-03-24 12:02:26 +0100
commit548e7432dc2da475a18077b612e8d55b8ff51891 (patch)
tree7901fc8bff98ceb6edf8381b7ba39533b58d9b37 /drivers/dma-buf
parentf30bceab16d1d6a97cbe262623e25ed2873896f0 (diff)
dma-buf: add dma_resv_replace_fences v2
This function allows to replace fences from the shared fence list when we can gurantee that the operation represented by the original fence has finished or no accesses to the resources protected by the dma_resv object any more when the new fence finishes. Then use this function in the amdkfd code when BOs are unmapped from the process. v2: add an example when this is usefull. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20220321135856.1331-1-christian.koenig@amd.com
Diffstat (limited to 'drivers/dma-buf')
-rw-r--r--drivers/dma-buf/dma-resv.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index b51416405e86..509060861cf3 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -290,6 +290,51 @@ replace:
EXPORT_SYMBOL(dma_resv_add_shared_fence);
/**
+ * dma_resv_replace_fences - replace fences in the dma_resv obj
+ * @obj: the reservation object
+ * @context: the context of the fences to replace
+ * @replacement: the new fence to use instead
+ *
+ * Replace fences with a specified context with a new fence. Only valid if the
+ * operation represented by the original fence has no longer access to the
+ * resources represented by the dma_resv object when the new fence completes.
+ *
+ * And example for using this is replacing a preemption fence with a page table
+ * update fence which makes the resource inaccessible.
+ */
+void dma_resv_replace_fences(struct dma_resv *obj, uint64_t context,
+ struct dma_fence *replacement)
+{
+ struct dma_resv_list *list;
+ struct dma_fence *old;
+ unsigned int i;
+
+ dma_resv_assert_held(obj);
+
+ write_seqcount_begin(&obj->seq);
+
+ old = dma_resv_excl_fence(obj);
+ if (old->context == context) {
+ RCU_INIT_POINTER(obj->fence_excl, dma_fence_get(replacement));
+ dma_fence_put(old);
+ }
+
+ list = dma_resv_shared_list(obj);
+ for (i = 0; list && i < list->shared_count; ++i) {
+ old = rcu_dereference_protected(list->shared[i],
+ dma_resv_held(obj));
+ if (old->context != context)
+ continue;
+
+ rcu_assign_pointer(list->shared[i], dma_fence_get(replacement));
+ dma_fence_put(old);
+ }
+
+ write_seqcount_end(&obj->seq);
+}
+EXPORT_SYMBOL(dma_resv_replace_fences);
+
+/**
* dma_resv_add_excl_fence - Add an exclusive fence.
* @obj: the reservation object
* @fence: the exclusive fence to add