From: Anuj Gupta <anuj1072538@gmail.com>
To: kbusch@kernel.org, hch@lst.de, sagi@grimberg.me, axboe@kernel.dk
Cc: asml.silence@gmail.com, joshi.k@samsung.com,
linux-nvme@lists.infradead.org, linux-block@vger.kernel.org,
io-uring@vger.kernel.org, Anuj Gupta <anuj20.g@samsung.com>
Subject: [PATCH] nvme/io_uring: enable dma-buf backed passthrough I/O
Date: Fri, 16 Oct 2026 16:04:20 +0530 [thread overview]
Message-ID: <20261016103453.1129150-1-anuj1072538@gmail.com> (raw)
From: Anuj Gupta <anuj20.g@samsung.com>
Allow registering a dma-buf against an NVMe namespace character device
and using it as the data buffer of fixed uring_cmd passthrough I/O.
io_uring_cmd_import_fixed() now accepts dma-buf buffers and attaches
the current map. blk_rq_map_user_iov() maps dma-buf iterators directly,
since they cannot fall back to a bounce copy.
Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
---
block/blk-map.c | 9 ++++++++-
drivers/nvme/host/core.c | 13 +++++++++++++
drivers/nvme/host/ioctl.c | 1 +
include/linux/io_uring/cmd.h | 6 ++++++
io_uring/uring_cmd.c | 16 +++++++++++++++-
5 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/block/blk-map.c b/block/blk-map.c
index 9cb9605d1f62..8f03e21fd5fe 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -459,7 +459,7 @@ int blk_rq_append_bio(struct request *rq, struct bio *bio)
}
EXPORT_SYMBOL(blk_rq_append_bio);
-/* Prepare bio for passthrough IO given ITER_BVEC iter */
+/* Prepare a bio for passthrough I/O from a directly mapped iterator. */
static int blk_rq_map_user_bvec(struct request *rq, const struct iov_iter *iter)
{
unsigned int max_bytes = rq->q->limits.max_hw_sectors << SECTOR_SHIFT;
@@ -506,6 +506,13 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
struct iov_iter i;
int ret = -EINVAL;
+ if (iov_iter_is_dmabuf_map(iter)) {
+ if (map_data || (iov_iter_alignment(iter) & align))
+ return -EINVAL;
+ ret = blk_rq_map_user_bvec(rq, iter);
+ return ret == -EREMOTEIO ? -EINVAL : ret;
+ }
+
if (map_data)
copy = true;
else if (iov_iter_alignment(iter) & align)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index d81462e864a4..29c29dad06b8 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3982,6 +3982,18 @@ static int nvme_ns_chr_release(struct inode *inode, struct file *file)
return 0;
}
+static int nvme_ns_chr_init_dma_buf_io_ctx(struct file *file,
+ struct dma_buf_io_ctx *ctx)
+{
+ struct nvme_ns *ns = container_of(file_inode(file)->i_cdev,
+ struct nvme_ns, cdev);
+ struct nvme_ctrl *ctrl = ns->ctrl;
+
+ if (!ctrl->ops->init_dma_buf_io_ctx)
+ return -EINVAL;
+ return ctrl->ops->init_dma_buf_io_ctx(ctrl, ctx);
+}
+
static const struct file_operations nvme_ns_chr_fops = {
.owner = THIS_MODULE,
.open = nvme_ns_chr_open,
@@ -3990,6 +4002,7 @@ static const struct file_operations nvme_ns_chr_fops = {
.compat_ioctl = compat_ptr_ioctl,
.uring_cmd = nvme_ns_chr_uring_cmd,
.uring_cmd_iopoll = nvme_ns_chr_uring_cmd_iopoll,
+ .init_dma_buf_io_ctx = nvme_ns_chr_init_dma_buf_io_ctx,
};
static void nvme_add_ns_cdev(struct nvme_ns *ns)
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 3aa5d2f2dfbb..6343da1f6c05 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -458,6 +458,7 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
status = blk_status_to_errno(err);
}
io_uring_cmd_set_res32(ioucmd, status, result);
+ io_uring_cmd_detach_dmabuf(ioucmd);
/*
* For IOPOLL, check if this completion is happening in the context
diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h
index e18d4af62e1a..33e0ebeea5a0 100644
--- a/include/linux/io_uring/cmd.h
+++ b/include/linux/io_uring/cmd.h
@@ -70,6 +70,7 @@ int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd,
size_t uvec_segs,
int ddir, struct iov_iter *iter,
unsigned issue_flags);
+void io_uring_cmd_detach_dmabuf(struct io_uring_cmd *ioucmd);
/*
* Completes the request, i.e. posts an io_uring CQE and deallocates @ioucmd
@@ -136,6 +137,11 @@ static inline int io_uring_cmd_import_fixed_vec(struct io_uring_cmd *ioucmd,
{
return -EOPNOTSUPP;
}
+
+static inline void io_uring_cmd_detach_dmabuf(struct io_uring_cmd *ioucmd)
+{
+}
+
static inline void __io_uring_cmd_done(struct io_uring_cmd *cmd,
unsigned issue_flags)
{
diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c
index 73b606899833..0e0509edec6f 100644
--- a/io_uring/uring_cmd.c
+++ b/io_uring/uring_cmd.c
@@ -10,6 +10,7 @@
#include "io_uring.h"
#include "alloc_cache.h"
+#include "dma-buf.h"
#include "rsrc.h"
#include "kbuf.h"
#include "uring_cmd.h"
@@ -28,6 +29,7 @@ static void io_req_uring_cleanup(struct io_kiocb *req, unsigned int issue_flags)
struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
struct io_async_cmd *ac = req->async_data;
+ io_detach_dmabuf_map(req);
if (issue_flags & IO_URING_F_UNLOCKED)
return;
@@ -48,6 +50,12 @@ void io_uring_cmd_cleanup(struct io_kiocb *req)
io_req_uring_cleanup(req, 0);
}
+void io_uring_cmd_detach_dmabuf(struct io_uring_cmd *ioucmd)
+{
+ io_detach_dmabuf_map(cmd_to_io_kiocb(ioucmd));
+}
+EXPORT_SYMBOL_GPL(io_uring_cmd_detach_dmabuf);
+
bool io_uring_try_cancel_uring_cmd(struct io_ring_ctx *ctx,
struct io_uring_task *tctx)
{
@@ -257,6 +265,7 @@ int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags)
ret = file->f_op->uring_cmd(ioucmd, issue_flags);
if (ret == -EAGAIN) {
+ io_detach_dmabuf_map(req);
ioucmd->flags |= IORING_URING_CMD_REISSUE;
return ret;
}
@@ -275,11 +284,16 @@ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
unsigned int issue_flags)
{
struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
+ int ret;
if (WARN_ON_ONCE(!(ioucmd->flags & IORING_URING_CMD_FIXED)))
return -EINVAL;
- return io_import_reg_buf(req, iter, ubuf, len, rw, issue_flags);
+ ret = __io_import_reg_buf(req, iter, ubuf, len, rw, issue_flags,
+ IO_REGBUF_IMPORT_ALLOW_DMABUF);
+ if (ret)
+ return ret;
+ return io_attach_dmabuf_map(req, iter, issue_flags);
}
EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed);
--
2.43.0
next reply other threads:[~2026-10-16 10:35 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-16 10:34 Anuj Gupta [this message]
2026-10-16 10:41 ` [PATCH] nvme/io_uring: enable dma-buf backed passthrough I/O Anuj gupta
2026-10-16 12:28 ` Christoph Hellwig
2026-10-18 22:06 ` Pavel Begunkov
2026-10-19 13:40 ` Anuj Gupta
2026-10-21 14:23 ` Pavel Begunkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261016103453.1129150-1-anuj1072538@gmail.com \
--to=anuj1072538@gmail.com \
--cc=anuj20.g@samsung.com \
--cc=asml.silence@gmail.com \
--cc=axboe@kernel.dk \
--cc=hch@lst.de \
--cc=io-uring@vger.kernel.org \
--cc=joshi.k@samsung.com \
--cc=kbusch@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.