summaryrefslogtreecommitdiff
path: root/drivers/dma-buf
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2021-11-03 12:02:08 +0300
committerChristian König <christian.koenig@amd.com>2022-04-03 18:53:28 +0300
commit92cedee6a6a3e6fcc3ffc0e3866baae5f6f76ac1 (patch)
treeec31e50f6de3b5ebaaf8c17aa9e311dad3dcbb7e /drivers/dma-buf
parentd791aec9ff43df4ea0a6690eabd6c395e982ef6f (diff)
downloadlinux-92cedee6a6a3e6fcc3ffc0e3866baae5f6f76ac1.tar.xz
dma-buf: add dma_resv_get_singleton v2
Add a function to simplify getting a single fence for all the fences in the dma_resv object. v2: fix ref leak in error handling Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20220321135856.1331-3-christian.koenig@amd.com
Diffstat (limited to 'drivers/dma-buf')
-rw-r--r--drivers/dma-buf/dma-resv.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index be65522f0f47..ff16da0a54ec 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -34,6 +34,7 @@
*/
#include <linux/dma-resv.h>
+#include <linux/dma-fence-array.h>
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/sched/mm.h>
@@ -637,6 +638,59 @@ int dma_resv_get_fences(struct dma_resv *obj, bool write,
EXPORT_SYMBOL_GPL(dma_resv_get_fences);
/**
+ * dma_resv_get_singleton - Get a single fence for all the fences
+ * @obj: the reservation object
+ * @write: true if we should return all fences
+ * @fence: the resulting fence
+ *
+ * Get a single fence representing all the fences inside the resv object.
+ * Returns either 0 for success or -ENOMEM.
+ *
+ * Warning: This can't be used like this when adding the fence back to the resv
+ * object since that can lead to stack corruption when finalizing the
+ * dma_fence_array.
+ *
+ * Returns 0 on success and negative error values on failure.
+ */
+int dma_resv_get_singleton(struct dma_resv *obj, bool write,
+ struct dma_fence **fence)
+{
+ struct dma_fence_array *array;
+ struct dma_fence **fences;
+ unsigned count;
+ int r;
+
+ r = dma_resv_get_fences(obj, write, &count, &fences);
+ if (r)
+ return r;
+
+ if (count == 0) {
+ *fence = NULL;
+ return 0;
+ }
+
+ if (count == 1) {
+ *fence = fences[0];
+ kfree(fences);
+ return 0;
+ }
+
+ array = dma_fence_array_create(count, fences,
+ dma_fence_context_alloc(1),
+ 1, false);
+ if (!array) {
+ while (count--)
+ dma_fence_put(fences[count]);
+ kfree(fences);
+ return -ENOMEM;
+ }
+
+ *fence = &array->base;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dma_resv_get_singleton);
+
+/**
* dma_resv_wait_timeout - Wait on reservation's objects
* shared and/or exclusive fences.
* @obj: the reservation object