Add API of io_uring_cmd_lease_kbuf() for driver to lease its kernel buffer to io_uring. The leased buffer can only be consumed by io_uring OPs in group wide, and the uring_cmd has to be one group leader. This way can support generic device zero copy over device buffer in userspace: - create one sqe group - lease one device buffer to io_uring by the group leader of uring_cmd - io_uring member OPs consume this kernel buffer by passing IOSQE_IO_DRAIN which isn't used for group member, and mapped to GROUP_KBUF. - the kernel buffer is returned back after all member OPs are completed Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> --- include/linux/io_uring/cmd.h | 7 +++++++ io_uring/uring_cmd.c | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h index c189d36ad55e..bdf7abfa0d8a 100644 --- a/include/linux/io_uring/cmd.h +++ b/include/linux/io_uring/cmd.h @@ -60,6 +60,8 @@ void io_uring_cmd_mark_cancelable(struct io_uring_cmd *cmd, /* Execute the request from a blocking context */ void io_uring_cmd_issue_blocking(struct io_uring_cmd *ioucmd); +int io_uring_cmd_lease_kbuf(struct io_uring_cmd *ioucmd, + const struct io_uring_kernel_buf *grp_kbuf); #else static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw, struct iov_iter *iter, void *ioucmd) @@ -82,6 +84,11 @@ static inline void io_uring_cmd_mark_cancelable(struct io_uring_cmd *cmd, static inline void io_uring_cmd_issue_blocking(struct io_uring_cmd *ioucmd) { } +static inline int io_uring_cmd_lease_kbuf(struct io_uring_cmd *ioucmd, + const struct io_uring_kernel_buf *grp_kbuf) +{ + return -EOPNOTSUPP; +} #endif /* diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c index 6994f60d7ec7..2c9c2c60c6cd 100644 --- a/io_uring/uring_cmd.c +++ b/io_uring/uring_cmd.c @@ -15,6 +15,7 @@ #include "alloc_cache.h" #include "rsrc.h" #include "uring_cmd.h" +#include "kbuf.h" static struct uring_cache *io_uring_async_get(struct io_kiocb *req) { @@ -175,6 +176,18 @@ void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, ssize_t res2, } EXPORT_SYMBOL_GPL(io_uring_cmd_done); +int io_uring_cmd_lease_kbuf(struct io_uring_cmd *ioucmd, + const struct io_uring_kernel_buf *grp_kbuf) +{ + struct io_kiocb *req = cmd_to_io_kiocb(ioucmd); + + if (unlikely(ioucmd->flags & IORING_URING_CMD_FIXED)) + return -EINVAL; + + return io_lease_group_kbuf(req, grp_kbuf); +} +EXPORT_SYMBOL_GPL(io_uring_cmd_lease_kbuf); + static int io_uring_cmd_prep_setup(struct io_kiocb *req, const struct io_uring_sqe *sqe) { -- 2.46.0