Commit c19083c7 authored by Jason Ekstrand's avatar Jason Ekstrand Committed by Christian König
Browse files

dma-buf: Use dma_fence_unwrap_for_each when importing fences



Ever since 68129f43 ("dma-buf: warn about containers in dma_resv object"),
dma_resv_add_shared_fence will warn if you attempt to add a container fence.
While most drivers were fine, fences can also be added to a dma_resv via the
recently added DMA_BUF_IOCTL_IMPORT_SYNC_FILE.  Use dma_fence_unwrap_for_each
to add each fence one at a time.

Fixes: 59474049 ("dma-buf: Add an API for importing sync files (v10)")
Signed-off-by: default avatarJason Ekstrand <jason.ekstrand@collabora.com>
Reported-by: default avatarSarah Walker <Sarah.Walker@imgtec.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
CC: stable@vger.kernel.org
Link: https://patchwork.freedesktop.org/patch/msgid/20220802210158.4162525-1-jason.ekstrand@collabora.com


Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
parent b09d6acb
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/dma-buf.h>
#include <linux/dma-fence.h>
#include <linux/dma-fence-unwrap.h>
#include <linux/anon_inodes.h>
#include <linux/export.h>
#include <linux/debugfs.h>
@@ -391,8 +392,10 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
				     const void __user *user_data)
{
	struct dma_buf_import_sync_file arg;
	struct dma_fence *fence;
	struct dma_fence *fence, *f;
	enum dma_resv_usage usage;
	struct dma_fence_unwrap iter;
	unsigned int num_fences;
	int ret = 0;

	if (copy_from_user(&arg, user_data, sizeof(arg)))
@@ -411,13 +414,21 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
	usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE :
						   DMA_RESV_USAGE_READ;

	num_fences = 0;
	dma_fence_unwrap_for_each(f, &iter, fence)
		++num_fences;

	if (num_fences > 0) {
		dma_resv_lock(dmabuf->resv, NULL);

	ret = dma_resv_reserve_fences(dmabuf->resv, 1);
	if (!ret)
		dma_resv_add_fence(dmabuf->resv, fence, usage);
		ret = dma_resv_reserve_fences(dmabuf->resv, num_fences);
		if (!ret) {
			dma_fence_unwrap_for_each(f, &iter, fence)
				dma_resv_add_fence(dmabuf->resv, f, usage);
		}

		dma_resv_unlock(dmabuf->resv);
	}

	dma_fence_put(fence);