* [PATCH 1/2] dmabuf: add DMA_BUF_IOCTL_RW_FILE @ 2025-05-13 9:27 wangtao 2025-05-13 11:31 ` Christian König 0 siblings, 1 reply; 5+ messages in thread From: wangtao @ 2025-05-13 9:27 UTC (permalink / raw) To: sumit.semwal, christian.koenig, benjamin.gaignard, Brian.Starkey, jstultz, tjmercier Cc: linux-media, dri-devel, linaro-mm-sig, linux-kernel, bintian.wang, yipengxiang, liulu.liu, feng.han, wangtao Add DMA_BUF_IOCTL_RW_FILE to save/restore data from/to a dma-buf. Signed-off-by: wangtao <tao.wangtao@honor.com> --- drivers/dma-buf/dma-buf.c | 8 ++++++++ include/linux/dma-buf.h | 3 +++ include/uapi/linux/dma-buf.h | 29 +++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 5baa83b85515..95d8b0158ffd 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -460,6 +460,7 @@ static long dma_buf_ioctl(struct file *file, struct dma_buf *dmabuf; struct dma_buf_sync sync; enum dma_data_direction direction; + struct dma_buf_rw_file kfile; int ret; dmabuf = file->private_data; @@ -504,6 +505,13 @@ static long dma_buf_ioctl(struct file *file, return dma_buf_import_sync_file(dmabuf, (const void __user *)arg); #endif + case DMA_BUF_IOCTL_RW_FILE: + if (copy_from_user(&kfile, (void __user *) arg, sizeof(kfile))) + return -EFAULT; + if (!dmabuf->ops->rw_file) + return -EINVAL; + return dmabuf->ops->rw_file(dmabuf, &kfile); + default: return -ENOTTY; } diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 36216d28d8bd..de236ba2094b 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -22,6 +22,7 @@ #include <linux/fs.h> #include <linux/dma-fence.h> #include <linux/wait.h> +#include <uapi/linux/dma-buf.h> struct device; struct dma_buf; @@ -285,6 +286,8 @@ struct dma_buf_ops { int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map); void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map); + + int (*rw_file)(struct dma_buf *dmabuf, struct dma_buf_rw_file *file); }; /** diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h index 5a6fda66d9ad..ec9164b7b753 100644 --- a/include/uapi/linux/dma-buf.h +++ b/include/uapi/linux/dma-buf.h @@ -167,6 +167,29 @@ struct dma_buf_import_sync_file { __s32 fd; }; +/** + * struct dma_buf_rw_file - read/write file associated with a dma-buf + * + * Userspace can performs a DMA_BUF_IOCTL_BACK to save data from a dma-buf or + * restore data to a dma-buf. + */ +struct dma_buf_rw_file { + + /** @flags: Flags indicating read/write for this dma-buf. */ + __u32 flags; + /** @fd: File descriptor of the file associated with this dma-buf. */ + __s32 fd; + /** @file_offset: Offset within the file where this dma-buf starts. + * + * Offset and Length must be page-aligned for direct I/O. + */ + __u64 file_offset; + /** @buf_offset: Offset within this dma-buf where the read/write starts. */ + __u64 buf_offset; + /** @buf_len: Length of this dma-buf read/write. */ + __u64 buf_len; +}; + #define DMA_BUF_BASE 'b' #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) @@ -179,4 +202,10 @@ struct dma_buf_import_sync_file { #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file) #define DMA_BUF_IOCTL_IMPORT_SYNC_FILE _IOW(DMA_BUF_BASE, 3, struct dma_buf_import_sync_file) +#define DMA_BUF_RW_FLAGS_OP_MASK (0xFF << 0) +#define DMA_BUF_RW_FLAGS_READ (1 << 0) /* Restore dma-buf data */ +#define DMA_BUF_RW_FLAGS_WRITE (2 << 0) /* Save dma-buf data */ +#define DMA_BUF_RW_FLAGS_DIRECT (1u << 31) /* Direct read/write file */ +#define DMA_BUF_IOCTL_RW_FILE _IOW(DMA_BUF_BASE, 4, struct dma_buf_rw_file) + #endif -- 2.17.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] dmabuf: add DMA_BUF_IOCTL_RW_FILE 2025-05-13 9:27 [PATCH 1/2] dmabuf: add DMA_BUF_IOCTL_RW_FILE wangtao @ 2025-05-13 11:31 ` Christian König 2025-05-13 12:27 ` wangtao 2025-05-13 15:55 ` T.J. Mercier 0 siblings, 2 replies; 5+ messages in thread From: Christian König @ 2025-05-13 11:31 UTC (permalink / raw) To: wangtao, sumit.semwal, benjamin.gaignard, Brian.Starkey, jstultz, tjmercier Cc: linux-media, dri-devel, linaro-mm-sig, linux-kernel, bintian.wang, yipengxiang, liulu.liu, feng.han On 5/13/25 11:27, wangtao wrote: > Add DMA_BUF_IOCTL_RW_FILE to save/restore data from/to a dma-buf. Similar approach where rejected before in favor of using udmabuf. Is there any reason you can't use that approach as well? Regards, Christian. > > Signed-off-by: wangtao <tao.wangtao@honor.com> > --- > drivers/dma-buf/dma-buf.c | 8 ++++++++ > include/linux/dma-buf.h | 3 +++ > include/uapi/linux/dma-buf.h | 29 +++++++++++++++++++++++++++++ > 3 files changed, 40 insertions(+) > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > index 5baa83b85515..95d8b0158ffd 100644 > --- a/drivers/dma-buf/dma-buf.c > +++ b/drivers/dma-buf/dma-buf.c > @@ -460,6 +460,7 @@ static long dma_buf_ioctl(struct file *file, > struct dma_buf *dmabuf; > struct dma_buf_sync sync; > enum dma_data_direction direction; > + struct dma_buf_rw_file kfile; > int ret; > > dmabuf = file->private_data; > @@ -504,6 +505,13 @@ static long dma_buf_ioctl(struct file *file, > return dma_buf_import_sync_file(dmabuf, (const void __user *)arg); > #endif > > + case DMA_BUF_IOCTL_RW_FILE: > + if (copy_from_user(&kfile, (void __user *) arg, sizeof(kfile))) > + return -EFAULT; > + if (!dmabuf->ops->rw_file) > + return -EINVAL; > + return dmabuf->ops->rw_file(dmabuf, &kfile); > + > default: > return -ENOTTY; > } > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h > index 36216d28d8bd..de236ba2094b 100644 > --- a/include/linux/dma-buf.h > +++ b/include/linux/dma-buf.h > @@ -22,6 +22,7 @@ > #include <linux/fs.h> > #include <linux/dma-fence.h> > #include <linux/wait.h> > +#include <uapi/linux/dma-buf.h> > > struct device; > struct dma_buf; > @@ -285,6 +286,8 @@ struct dma_buf_ops { > > int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map); > void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map); > + > + int (*rw_file)(struct dma_buf *dmabuf, struct dma_buf_rw_file *file); > }; > > /** > diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h > index 5a6fda66d9ad..ec9164b7b753 100644 > --- a/include/uapi/linux/dma-buf.h > +++ b/include/uapi/linux/dma-buf.h > @@ -167,6 +167,29 @@ struct dma_buf_import_sync_file { > __s32 fd; > }; > > +/** > + * struct dma_buf_rw_file - read/write file associated with a dma-buf > + * > + * Userspace can performs a DMA_BUF_IOCTL_BACK to save data from a dma-buf or > + * restore data to a dma-buf. > + */ > +struct dma_buf_rw_file { > + > + /** @flags: Flags indicating read/write for this dma-buf. */ > + __u32 flags; > + /** @fd: File descriptor of the file associated with this dma-buf. */ > + __s32 fd; > + /** @file_offset: Offset within the file where this dma-buf starts. > + * > + * Offset and Length must be page-aligned for direct I/O. > + */ > + __u64 file_offset; > + /** @buf_offset: Offset within this dma-buf where the read/write starts. */ > + __u64 buf_offset; > + /** @buf_len: Length of this dma-buf read/write. */ > + __u64 buf_len; > +}; > + > #define DMA_BUF_BASE 'b' > #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) > > @@ -179,4 +202,10 @@ struct dma_buf_import_sync_file { > #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file) > #define DMA_BUF_IOCTL_IMPORT_SYNC_FILE _IOW(DMA_BUF_BASE, 3, struct dma_buf_import_sync_file) > > +#define DMA_BUF_RW_FLAGS_OP_MASK (0xFF << 0) > +#define DMA_BUF_RW_FLAGS_READ (1 << 0) /* Restore dma-buf data */ > +#define DMA_BUF_RW_FLAGS_WRITE (2 << 0) /* Save dma-buf data */ > +#define DMA_BUF_RW_FLAGS_DIRECT (1u << 31) /* Direct read/write file */ > +#define DMA_BUF_IOCTL_RW_FILE _IOW(DMA_BUF_BASE, 4, struct dma_buf_rw_file) > + > #endif ^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH 1/2] dmabuf: add DMA_BUF_IOCTL_RW_FILE 2025-05-13 11:31 ` Christian König @ 2025-05-13 12:27 ` wangtao 2025-05-13 15:55 ` T.J. Mercier 1 sibling, 0 replies; 5+ messages in thread From: wangtao @ 2025-05-13 12:27 UTC (permalink / raw) To: Christian König, sumit.semwal@linaro.org, benjamin.gaignard@collabora.com, Brian.Starkey@arm.com, jstultz@google.com, tjmercier@google.com Cc: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org, wangbintian(BintianWang), yipengxiang, liulu 00013167, hanfeng 00012985 > -----Original Message----- > From: Christian König <christian.koenig@amd.com> > Sent: Tuesday, May 13, 2025 7:31 PM > To: wangtao <tao.wangtao@honor.com>; sumit.semwal@linaro.org; > benjamin.gaignard@collabora.com; Brian.Starkey@arm.com; > jstultz@google.com; tjmercier@google.com > Cc: linux-media@vger.kernel.org; dri-devel@lists.freedesktop.org; linaro- > mm-sig@lists.linaro.org; linux-kernel@vger.kernel.org; > wangbintian(BintianWang) <bintian.wang@honor.com>; yipengxiang > <yipengxiang@honor.com>; liulu 00013167 <liulu.liu@honor.com>; hanfeng > 00012985 <feng.han@honor.com> > Subject: Re: [PATCH 1/2] dmabuf: add DMA_BUF_IOCTL_RW_FILE > > On 5/13/25 11:27, wangtao wrote: > > Add DMA_BUF_IOCTL_RW_FILE to save/restore data from/to a dma-buf. > > Similar approach where rejected before in favor of using udmabuf. > > Is there any reason you can't use that approach as well? [wangtao] For performance optimization, we can achieves 3776 MB/s (UFS 4.0 device @ 4GB/s). Apologies, my three previous emails were not consolidated into the same thread. > > Regards, > Christian. > > > > > Signed-off-by: wangtao <tao.wangtao@honor.com> > > --- > > drivers/dma-buf/dma-buf.c | 8 ++++++++ > > include/linux/dma-buf.h | 3 +++ > > include/uapi/linux/dma-buf.h | 29 +++++++++++++++++++++++++++++ > > 3 files changed, 40 insertions(+) > > > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > > index 5baa83b85515..95d8b0158ffd 100644 > > --- a/drivers/dma-buf/dma-buf.c > > +++ b/drivers/dma-buf/dma-buf.c > > @@ -460,6 +460,7 @@ static long dma_buf_ioctl(struct file *file, > > struct dma_buf *dmabuf; > > struct dma_buf_sync sync; > > enum dma_data_direction direction; > > + struct dma_buf_rw_file kfile; > > int ret; > > > > dmabuf = file->private_data; > > @@ -504,6 +505,13 @@ static long dma_buf_ioctl(struct file *file, > > return dma_buf_import_sync_file(dmabuf, (const void > __user *)arg); > > #endif > > > > + case DMA_BUF_IOCTL_RW_FILE: > > + if (copy_from_user(&kfile, (void __user *) arg, sizeof(kfile))) > > + return -EFAULT; > > + if (!dmabuf->ops->rw_file) > > + return -EINVAL; > > + return dmabuf->ops->rw_file(dmabuf, &kfile); > > + > > default: > > return -ENOTTY; > > } > > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index > > 36216d28d8bd..de236ba2094b 100644 > > --- a/include/linux/dma-buf.h > > +++ b/include/linux/dma-buf.h > > @@ -22,6 +22,7 @@ > > #include <linux/fs.h> > > #include <linux/dma-fence.h> > > #include <linux/wait.h> > > +#include <uapi/linux/dma-buf.h> > > > > struct device; > > struct dma_buf; > > @@ -285,6 +286,8 @@ struct dma_buf_ops { > > > > int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map); > > void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map); > > + > > + int (*rw_file)(struct dma_buf *dmabuf, struct dma_buf_rw_file > > +*file); > > }; > > > > /** > > diff --git a/include/uapi/linux/dma-buf.h > > b/include/uapi/linux/dma-buf.h index 5a6fda66d9ad..ec9164b7b753 > 100644 > > --- a/include/uapi/linux/dma-buf.h > > +++ b/include/uapi/linux/dma-buf.h > > @@ -167,6 +167,29 @@ struct dma_buf_import_sync_file { > > __s32 fd; > > }; > > > > +/** > > + * struct dma_buf_rw_file - read/write file associated with a dma-buf > > + * > > + * Userspace can performs a DMA_BUF_IOCTL_BACK to save data from a > > +dma-buf or > > + * restore data to a dma-buf. > > + */ > > +struct dma_buf_rw_file { > > + > > + /** @flags: Flags indicating read/write for this dma-buf. */ > > + __u32 flags; > > + /** @fd: File descriptor of the file associated with this dma-buf. */ > > + __s32 fd; > > + /** @file_offset: Offset within the file where this dma-buf starts. > > + * > > + * Offset and Length must be page-aligned for direct I/O. > > + */ > > + __u64 file_offset; > > + /** @buf_offset: Offset within this dma-buf where the read/write > starts. */ > > + __u64 buf_offset; > > + /** @buf_len: Length of this dma-buf read/write. */ > > + __u64 buf_len; > > +}; > > + > > #define DMA_BUF_BASE 'b' > > #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct > dma_buf_sync) > > > > @@ -179,4 +202,10 @@ struct dma_buf_import_sync_file { > > #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE > _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file) > > #define DMA_BUF_IOCTL_IMPORT_SYNC_FILE > _IOW(DMA_BUF_BASE, 3, struct dma_buf_import_sync_file) > > > > +#define DMA_BUF_RW_FLAGS_OP_MASK (0xFF << 0) #define > > +DMA_BUF_RW_FLAGS_READ (1 << 0) /* Restore dma-buf data */ > #define > > +DMA_BUF_RW_FLAGS_WRITE (2 << 0) /* Save dma-buf data */ #define > > +DMA_BUF_RW_FLAGS_DIRECT (1u << 31) /* Direct read/write file */ > > +#define DMA_BUF_IOCTL_RW_FILE _IOW(DMA_BUF_BASE, 4, struct > dma_buf_rw_file) > > + > > #endif ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] dmabuf: add DMA_BUF_IOCTL_RW_FILE 2025-05-13 11:31 ` Christian König 2025-05-13 12:27 ` wangtao @ 2025-05-13 15:55 ` T.J. Mercier 2025-05-13 16:13 ` Christian König 1 sibling, 1 reply; 5+ messages in thread From: T.J. Mercier @ 2025-05-13 15:55 UTC (permalink / raw) To: Christian König Cc: wangtao, sumit.semwal, benjamin.gaignard, Brian.Starkey, jstultz, linux-media, dri-devel, linaro-mm-sig, linux-kernel, bintian.wang, yipengxiang, liulu.liu, feng.han [-- Attachment #1: Type: text/plain, Size: 4496 bytes --] On Tue, May 13, 2025 at 4:31 AM Christian König <christian.koenig@amd.com> wrote: > > On 5/13/25 11:27, wangtao wrote: > > Add DMA_BUF_IOCTL_RW_FILE to save/restore data from/to a dma-buf. > > Similar approach where rejected before in favor of using udmabuf. > > Is there any reason you can't use that approach as well? I also recently verified that udmabuf + O_DIRECT works with sendfile(), and you can even MADV_COLLAPSE the underlying shmem if you want. > Regards, > Christian. > > > > > Signed-off-by: wangtao <tao.wangtao@honor.com> > > --- > > drivers/dma-buf/dma-buf.c | 8 ++++++++ > > include/linux/dma-buf.h | 3 +++ > > include/uapi/linux/dma-buf.h | 29 +++++++++++++++++++++++++++++ > > 3 files changed, 40 insertions(+) > > > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > > index 5baa83b85515..95d8b0158ffd 100644 > > --- a/drivers/dma-buf/dma-buf.c > > +++ b/drivers/dma-buf/dma-buf.c > > @@ -460,6 +460,7 @@ static long dma_buf_ioctl(struct file *file, > > struct dma_buf *dmabuf; > > struct dma_buf_sync sync; > > enum dma_data_direction direction; > > + struct dma_buf_rw_file kfile; > > int ret; > > > > dmabuf = file->private_data; > > @@ -504,6 +505,13 @@ static long dma_buf_ioctl(struct file *file, > > return dma_buf_import_sync_file(dmabuf, (const void __user *)arg); > > #endif > > > > + case DMA_BUF_IOCTL_RW_FILE: > > + if (copy_from_user(&kfile, (void __user *) arg, sizeof(kfile))) > > + return -EFAULT; > > + if (!dmabuf->ops->rw_file) > > + return -EINVAL; > > + return dmabuf->ops->rw_file(dmabuf, &kfile); > > + > > default: > > return -ENOTTY; > > } > > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h > > index 36216d28d8bd..de236ba2094b 100644 > > --- a/include/linux/dma-buf.h > > +++ b/include/linux/dma-buf.h > > @@ -22,6 +22,7 @@ > > #include <linux/fs.h> > > #include <linux/dma-fence.h> > > #include <linux/wait.h> > > +#include <uapi/linux/dma-buf.h> > > > > struct device; > > struct dma_buf; > > @@ -285,6 +286,8 @@ struct dma_buf_ops { > > > > int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map); > > void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map); > > + > > + int (*rw_file)(struct dma_buf *dmabuf, struct dma_buf_rw_file *file); > > }; > > > > /** > > diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h > > index 5a6fda66d9ad..ec9164b7b753 100644 > > --- a/include/uapi/linux/dma-buf.h > > +++ b/include/uapi/linux/dma-buf.h > > @@ -167,6 +167,29 @@ struct dma_buf_import_sync_file { > > __s32 fd; > > }; > > > > +/** > > + * struct dma_buf_rw_file - read/write file associated with a dma-buf > > + * > > + * Userspace can performs a DMA_BUF_IOCTL_BACK to save data from a dma-buf or > > + * restore data to a dma-buf. > > + */ > > +struct dma_buf_rw_file { > > + > > + /** @flags: Flags indicating read/write for this dma-buf. */ > > + __u32 flags; > > + /** @fd: File descriptor of the file associated with this dma-buf. */ > > + __s32 fd; > > + /** @file_offset: Offset within the file where this dma-buf starts. > > + * > > + * Offset and Length must be page-aligned for direct I/O. > > + */ > > + __u64 file_offset; > > + /** @buf_offset: Offset within this dma-buf where the read/write starts. */ > > + __u64 buf_offset; > > + /** @buf_len: Length of this dma-buf read/write. */ > > + __u64 buf_len; > > +}; > > + > > #define DMA_BUF_BASE 'b' > > #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) > > > > @@ -179,4 +202,10 @@ struct dma_buf_import_sync_file { > > #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file) > > #define DMA_BUF_IOCTL_IMPORT_SYNC_FILE _IOW(DMA_BUF_BASE, 3, struct dma_buf_import_sync_file) > > > > +#define DMA_BUF_RW_FLAGS_OP_MASK (0xFF << 0) > > +#define DMA_BUF_RW_FLAGS_READ (1 << 0) /* Restore dma-buf data */ > > +#define DMA_BUF_RW_FLAGS_WRITE (2 << 0) /* Save dma-buf data */ > > +#define DMA_BUF_RW_FLAGS_DIRECT (1u << 31) /* Direct read/write file */ > > +#define DMA_BUF_IOCTL_RW_FILE _IOW(DMA_BUF_BASE, 4, struct dma_buf_rw_file) > > + > > #endif > [-- Attachment #2: udmabuf_odirect.cpp --] [-- Type: text/x-c++src, Size: 1898 bytes --] #include <cstdlib> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/sendfile.h> #include <unistd.h> #include <linux/udmabuf.h> namespace { int createMemfd(size_t bytes, unsigned int flags) { int fd(memfd_create("memfd_test", flags)); if (fd == -1) { perror("memfd_create"); return -1; } int rc = ftruncate(fd, bytes); if (rc == -1) { perror("ftruncate"); return -1; } return fd; } int createUdmabuf(size_t bytes, int memfd) { int udmabuf_dev_fd(open("/dev/udmabuf", O_RDONLY)); if (udmabuf_dev_fd == -1) { perror("udmabuf open"); return -1; } struct udmabuf_create create; create.memfd = memfd; create.flags = UDMABUF_FLAGS_CLOEXEC; create.offset = 0; create.size = bytes; int dmabuf_fd(ioctl(udmabuf_dev_fd, UDMABUF_CREATE, &create)); if (dmabuf_fd == -1) perror("UDMABUF_CREATE"); return dmabuf_fd; } } // anonymous namespace int main(int argc, char **argv) { size_t bytes = 1ull << 30; int memfd = createMemfd(bytes, MFD_ALLOW_SEALING); if (memfd < 0) return EXIT_FAILURE; if (fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK) < 0) { perror("F_SEAL_SHRINK"); return EXIT_FAILURE; } if (ftruncate(memfd, bytes)) { perror("ftruncate"); return EXIT_FAILURE; } int bigfile = open(argv[1], O_RDONLY | O_DIRECT); if (bigfile < 0) { perror("open"); return EXIT_FAILURE; } off_t offset = 0; for (ssize_t n = sendfile(memfd, bigfile, &offset, bytes - offset); offset < bytes && n > 0; n = sendfile(memfd, bigfile, &offset, bytes - offset)) {} printf("Offset %ld\n", offset); int udmabuf = createUdmabuf(bytes, memfd); if (udmabuf < 0) return EXIT_FAILURE; return EXIT_SUCCESS; } ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] dmabuf: add DMA_BUF_IOCTL_RW_FILE 2025-05-13 15:55 ` T.J. Mercier @ 2025-05-13 16:13 ` Christian König 0 siblings, 0 replies; 5+ messages in thread From: Christian König @ 2025-05-13 16:13 UTC (permalink / raw) To: T.J. Mercier Cc: wangtao, sumit.semwal, benjamin.gaignard, Brian.Starkey, jstultz, linux-media, dri-devel, linaro-mm-sig, linux-kernel, bintian.wang, yipengxiang, liulu.liu, feng.han On 5/13/25 17:55, T.J. Mercier wrote: > On Tue, May 13, 2025 at 4:31 AM Christian König > <christian.koenig@amd.com> wrote: >> >> On 5/13/25 11:27, wangtao wrote: >>> Add DMA_BUF_IOCTL_RW_FILE to save/restore data from/to a dma-buf. >> >> Similar approach where rejected before in favor of using udmabuf. >> >> Is there any reason you can't use that approach as well? > > I also recently verified that udmabuf + O_DIRECT works with > sendfile(), and you can even MADV_COLLAPSE the underlying shmem if you > want. Oh, nice :) Going to keep that in mind if somebody ask for that feature again. Regards, Christian. > >> Regards, >> Christian. >> >>> >>> Signed-off-by: wangtao <tao.wangtao@honor.com> >>> --- >>> drivers/dma-buf/dma-buf.c | 8 ++++++++ >>> include/linux/dma-buf.h | 3 +++ >>> include/uapi/linux/dma-buf.h | 29 +++++++++++++++++++++++++++++ >>> 3 files changed, 40 insertions(+) >>> >>> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c >>> index 5baa83b85515..95d8b0158ffd 100644 >>> --- a/drivers/dma-buf/dma-buf.c >>> +++ b/drivers/dma-buf/dma-buf.c >>> @@ -460,6 +460,7 @@ static long dma_buf_ioctl(struct file *file, >>> struct dma_buf *dmabuf; >>> struct dma_buf_sync sync; >>> enum dma_data_direction direction; >>> + struct dma_buf_rw_file kfile; >>> int ret; >>> >>> dmabuf = file->private_data; >>> @@ -504,6 +505,13 @@ static long dma_buf_ioctl(struct file *file, >>> return dma_buf_import_sync_file(dmabuf, (const void __user *)arg); >>> #endif >>> >>> + case DMA_BUF_IOCTL_RW_FILE: >>> + if (copy_from_user(&kfile, (void __user *) arg, sizeof(kfile))) >>> + return -EFAULT; >>> + if (!dmabuf->ops->rw_file) >>> + return -EINVAL; >>> + return dmabuf->ops->rw_file(dmabuf, &kfile); >>> + >>> default: >>> return -ENOTTY; >>> } >>> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h >>> index 36216d28d8bd..de236ba2094b 100644 >>> --- a/include/linux/dma-buf.h >>> +++ b/include/linux/dma-buf.h >>> @@ -22,6 +22,7 @@ >>> #include <linux/fs.h> >>> #include <linux/dma-fence.h> >>> #include <linux/wait.h> >>> +#include <uapi/linux/dma-buf.h> >>> >>> struct device; >>> struct dma_buf; >>> @@ -285,6 +286,8 @@ struct dma_buf_ops { >>> >>> int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map); >>> void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map); >>> + >>> + int (*rw_file)(struct dma_buf *dmabuf, struct dma_buf_rw_file *file); >>> }; >>> >>> /** >>> diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h >>> index 5a6fda66d9ad..ec9164b7b753 100644 >>> --- a/include/uapi/linux/dma-buf.h >>> +++ b/include/uapi/linux/dma-buf.h >>> @@ -167,6 +167,29 @@ struct dma_buf_import_sync_file { >>> __s32 fd; >>> }; >>> >>> +/** >>> + * struct dma_buf_rw_file - read/write file associated with a dma-buf >>> + * >>> + * Userspace can performs a DMA_BUF_IOCTL_BACK to save data from a dma-buf or >>> + * restore data to a dma-buf. >>> + */ >>> +struct dma_buf_rw_file { >>> + >>> + /** @flags: Flags indicating read/write for this dma-buf. */ >>> + __u32 flags; >>> + /** @fd: File descriptor of the file associated with this dma-buf. */ >>> + __s32 fd; >>> + /** @file_offset: Offset within the file where this dma-buf starts. >>> + * >>> + * Offset and Length must be page-aligned for direct I/O. >>> + */ >>> + __u64 file_offset; >>> + /** @buf_offset: Offset within this dma-buf where the read/write starts. */ >>> + __u64 buf_offset; >>> + /** @buf_len: Length of this dma-buf read/write. */ >>> + __u64 buf_len; >>> +}; >>> + >>> #define DMA_BUF_BASE 'b' >>> #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) >>> >>> @@ -179,4 +202,10 @@ struct dma_buf_import_sync_file { >>> #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file) >>> #define DMA_BUF_IOCTL_IMPORT_SYNC_FILE _IOW(DMA_BUF_BASE, 3, struct dma_buf_import_sync_file) >>> >>> +#define DMA_BUF_RW_FLAGS_OP_MASK (0xFF << 0) >>> +#define DMA_BUF_RW_FLAGS_READ (1 << 0) /* Restore dma-buf data */ >>> +#define DMA_BUF_RW_FLAGS_WRITE (2 << 0) /* Save dma-buf data */ >>> +#define DMA_BUF_RW_FLAGS_DIRECT (1u << 31) /* Direct read/write file */ >>> +#define DMA_BUF_IOCTL_RW_FILE _IOW(DMA_BUF_BASE, 4, struct dma_buf_rw_file) >>> + >>> #endif >> ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-05-13 16:13 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-05-13 9:27 [PATCH 1/2] dmabuf: add DMA_BUF_IOCTL_RW_FILE wangtao 2025-05-13 11:31 ` Christian König 2025-05-13 12:27 ` wangtao 2025-05-13 15:55 ` T.J. Mercier 2025-05-13 16:13 ` Christian König
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox