From: Caleb Sander Mateos <csander@purestorage.com>
To: Jens Axboe <axboe@kernel.dk>, Keith Busch <kbusch@kernel.org>,
Christoph Hellwig <hch@lst.de>, Sagi Grimberg <sagi@grimberg.me>
Cc: io-uring@vger.kernel.org, linux-nvme@lists.infradead.org,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
Caleb Sander Mateos <csander@purestorage.com>
Subject: [PATCH 6/6] nvme/ioctl: support fixed buffer for metadata
Date: Wed, 9 Sep 2026 16:28:36 -0600 [thread overview]
Message-ID: <20260909222836.2475352-7-csander@purestorage.com> (raw)
In-Reply-To: <20260909222836.2475352-1-csander@purestorage.com>
io_uring NVMe passthrough supports using a "fixed" (registered) buffer
for data, but not metadata. On high-IOPS workloads, the pinning and
unpinning overhead for the metadata pages is significant and could be
avoided if fixed metadata buffers were supported.
Define a NVME_URING_CMD_FIXED_METADATA bit for the nvme_uring_cmd's
flags field (which is currently required to be 0) to indicate that the
metadata buffer belongs to a fixed buffer registered with the io_uring.
The metadata fixed buffer index is specified in a metadata_buf_index
field replacing the existing rsvd1 in nvme_uring_cmd.
If NVME_URING_CMD_FIXED_METADATA is set, the metadata iov_iter is
obtained from io_uring_cmd_import_fixed_metadata() instead of
iov_iter_ubuf().
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
---
drivers/nvme/host/ioctl.c | 21 ++++++++++++++++-----
include/uapi/linux/nvme_ioctl.h | 5 ++++-
2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 8e722184ecf1..4da8cf92c2e0 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -488,21 +488,22 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
struct iov_iter iter, meta_iter;
struct iov_iter *map_iter = NULL, *map_meta_iter = NULL;
struct request *req;
blk_opf_t rq_flags = 0;
blk_mq_req_flags_t blk_flags = 0;
+ u8 flags = READ_ONCE(cmd->flags);
u32 metadata_len, data_len;
u64 metadata, addr;
u32 timeout_ms;
int ddir;
int ret;
- c.common.opcode = READ_ONCE(cmd->opcode);
- c.common.flags = READ_ONCE(cmd->flags);
- if (c.common.flags)
+ if (flags & ~NVME_URING_CMD_FIXED_METADATA)
return -EINVAL;
+ c.common.opcode = READ_ONCE(cmd->opcode);
+ c.common.flags = 0;
c.common.command_id = 0;
c.common.nsid = cpu_to_le32(cmd->nsid);
if (!nvme_validate_passthru_nsid(ctrl, ns, le32_to_cpu(c.common.nsid)))
return -EINVAL;
@@ -539,12 +540,22 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
return ret;
map_iter = &iter;
}
if (data_len && metadata && metadata_len) {
- iov_iter_ubuf(&meta_iter, ddir, nvme_to_user_ptr(metadata),
- metadata_len);
+ if (flags & NVME_URING_CMD_FIXED_METADATA) {
+ u16 buf_index = READ_ONCE(cmd->metadata_buf_index);
+
+ ret = io_uring_cmd_import_fixed_metadata(
+ ioucmd, buf_index, metadata, metadata_len, ddir,
+ &meta_iter, issue_flags);
+ if (ret < 0)
+ return ret;
+ } else {
+ iov_iter_ubuf(&meta_iter, ddir, nvme_to_user_ptr(metadata),
+ metadata_len);
+ }
map_meta_iter = &meta_iter;
}
if (issue_flags & IO_URING_F_NONBLOCK) {
rq_flags |= REQ_NOWAIT;
diff --git a/include/uapi/linux/nvme_ioctl.h b/include/uapi/linux/nvme_ioctl.h
index 2f76cba67166..93973f636b48 100644
--- a/include/uapi/linux/nvme_ioctl.h
+++ b/include/uapi/linux/nvme_ioctl.h
@@ -68,15 +68,18 @@ struct nvme_passthru_cmd64 {
__u32 timeout_ms;
__u32 rsvd2;
__u64 result;
};
+/* struct nvme_uring_cmd flags field bits */
+#define NVME_URING_CMD_FIXED_METADATA (1U << 0)
+
/* same as struct nvme_passthru_cmd64, minus the 8b result field */
struct nvme_uring_cmd {
__u8 opcode;
__u8 flags;
- __u16 rsvd1;
+ __u16 metadata_buf_index;
__u32 nsid;
__u32 cdw2;
__u32 cdw3;
__u64 metadata;
__u64 addr;
--
2.55.0
prev parent reply other threads:[~2026-09-09 22:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-09 22:28 [PATCH 0/6] io_uring/nvme: support fixed buffer for metadata Caleb Sander Mateos
2026-09-09 22:28 ` [PATCH 1/6] bio-integrity: remove dead bio_integrity_copy_user() error path Caleb Sander Mateos
2026-09-09 22:28 ` [PATCH 2/6] nvme/ioctl: remove struct nvme_uring_data Caleb Sander Mateos
2026-09-09 22:28 ` [PATCH 3/6] blk-integrity: pass iov_iter to blk_rq_integrity_map_user() Caleb Sander Mateos
2026-09-09 22:28 ` [PATCH 4/6] nvme/ioctl: pass iov_iter to nvme_map_user_request() Caleb Sander Mateos
2026-09-09 22:28 ` [PATCH 5/6] io_uring/cmd: support fixed buffer for metadata Caleb Sander Mateos
2026-09-09 22:28 ` Caleb Sander Mateos [this message]
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=20260909222836.2475352-7-csander@purestorage.com \
--to=csander@purestorage.com \
--cc=axboe@kernel.dk \
--cc=hch@lst.de \
--cc=io-uring@vger.kernel.org \
--cc=kbusch@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@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.