Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dma-buf: Use dma_fence_unwrap_for_each when importing fences

Ever since 68129f431faa ("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: 594740497e99 ("dma-buf: Add an API for importing sync files (v10)")
Signed-off-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Reported-by: Sarah Walker <Sarah.Walker@imgtec.com>
Reviewed-by: Christian 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: Christian König <christian.koenig@amd.com>

authored by

Jason Ekstrand and committed by
Christian König
c19083c7 b09d6acb

+17 -6
+17 -6
drivers/dma-buf/dma-buf.c
··· 15 15 #include <linux/slab.h> 16 16 #include <linux/dma-buf.h> 17 17 #include <linux/dma-fence.h> 18 + #include <linux/dma-fence-unwrap.h> 18 19 #include <linux/anon_inodes.h> 19 20 #include <linux/export.h> 20 21 #include <linux/debugfs.h> ··· 392 391 const void __user *user_data) 393 392 { 394 393 struct dma_buf_import_sync_file arg; 395 - struct dma_fence *fence; 394 + struct dma_fence *fence, *f; 396 395 enum dma_resv_usage usage; 396 + struct dma_fence_unwrap iter; 397 + unsigned int num_fences; 397 398 int ret = 0; 398 399 399 400 if (copy_from_user(&arg, user_data, sizeof(arg))) ··· 414 411 usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE : 415 412 DMA_RESV_USAGE_READ; 416 413 417 - dma_resv_lock(dmabuf->resv, NULL); 414 + num_fences = 0; 415 + dma_fence_unwrap_for_each(f, &iter, fence) 416 + ++num_fences; 418 417 419 - ret = dma_resv_reserve_fences(dmabuf->resv, 1); 420 - if (!ret) 421 - dma_resv_add_fence(dmabuf->resv, fence, usage); 418 + if (num_fences > 0) { 419 + dma_resv_lock(dmabuf->resv, NULL); 422 420 423 - dma_resv_unlock(dmabuf->resv); 421 + ret = dma_resv_reserve_fences(dmabuf->resv, num_fences); 422 + if (!ret) { 423 + dma_fence_unwrap_for_each(f, &iter, fence) 424 + dma_resv_add_fence(dmabuf->resv, f, usage); 425 + } 426 + 427 + dma_resv_unlock(dmabuf->resv); 428 + } 424 429 425 430 dma_fence_put(fence); 426 431