From: Christoph Hellwig <hch@lst.de>
To: Andrei-Alexandru Bleortu <me@andrei-z.com>
Cc: Keith Busch <kbusch@kernel.org>, Jens Axboe <axboe@kernel.dk>,
Christoph Hellwig <hch@lst.de>, Sagi Grimberg <sagi@grimberg.me>,
linux-nvme@lists.infradead.org, linux-rdma@vger.kernel.org
Subject: Re: [PATCH 1/1] nvme-rdma: post the command capsule inline when it fits
Date: Wed, 28 Oct 2026 15:49:51 +0100 [thread overview]
Message-ID: <20261028144951.GA14583@lst.de> (raw)
In-Reply-To: <20261015124823.2962700-2-me@andrei-z.com>
Can you reworkd the commit log to be concise? Also I find it really
annoying that a ULP would have to decide this. Doing inline submission
should really be something the core/LLDD takes care of.
On Thu, Oct 15, 2026 at 03:48:23PM +0300, Andrei-Alexandru Bleortu wrote:
> nvme_rdma_post_send() posts the 64-byte command capsule by reference,
> so the HCA has to DMA-read the capsule from host memory before it can
> send the command. That read is on the latency path of every I/O.
>
> Ask for sizeof(struct nvme_command) bytes of inline data when creating
> the queue pair, and create it without inline data if the device refuses.
> Post a capsule that has no in-capsule data with IB_SEND_INLINE when it
> fits in the granted inline size. The CPU then copies the capsule into
> the send WQE and the HCA no longer reads it.
>
> Providers copy inline data from sg_list[].addr as a kernel virtual
> address, but nvme-rdma keeps the capsule's DMA address there. On the
> inline path the SGE therefore points at qe->data. The capsule stays
> DMA-mapped for the by-reference path.
>
> An earlier version of this patch was measured with fio doing 4 KiB
> random reads at queue depth 1 against a null_blk namespace exported by
> nvmet-rdma. Both host pairs ran a 6.8 kernel over RoCEv2 at 100 Gb/s.
> The mean completion latency fell by 0.998 us (95% CI 0.943-1.049)
> between two AMD EPYC 7452 hosts with ConnectX-5 Ex, and by 0.589 us
> (0.558-0.618) between two Xeon Platinum 8360Y hosts with ConnectX-6 Dx.
> IOPS rose by 3.3% on the EPYC pair. A run there that asked for inline
> data but kept posting by reference showed no change. That version asked
> for 220 bytes and had no fallback, but it inlined the same capsules.
>
> Assisted-by: LLM
> Signed-off-by: Andrei-Alexandru Bleortu <me@andrei-z.com>
> ---
> drivers/nvme/host/rdma.c | 28 ++++++++++++++++++++++++++--
> 1 file changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
> index 5b9b540693b5..517098ebffb1 100644
> --- a/drivers/nvme/host/rdma.c
> +++ b/drivers/nvme/host/rdma.c
> @@ -106,6 +106,7 @@ struct nvme_rdma_queue {
> bool pi_support;
> int cq_size;
> struct mutex queue_lock;
> + u32 max_inline_data;
> };
>
> struct nvme_rdma_setup_ctx {
> @@ -265,7 +266,7 @@ static int nvme_rdma_wait_for_cm(struct nvme_rdma_queue *queue)
> static int nvme_rdma_create_qp(struct nvme_rdma_queue *queue, const int factor)
> {
> struct nvme_rdma_device *dev = queue->device;
> - struct ib_qp_init_attr init_attr;
> + struct ib_qp_init_attr init_attr, attr;
> int ret;
>
> memset(&init_attr, 0, sizeof(init_attr));
> @@ -284,9 +285,21 @@ static int nvme_rdma_create_qp(struct nvme_rdma_queue *queue, const int factor)
> init_attr.create_flags |= IB_QP_CREATE_INTEGRITY_EN;
> init_attr.qp_context = queue;
>
> - ret = rdma_create_qp(queue->cm_id, dev->pd, &init_attr);
> + /*
> + * Ask for enough inline data to carry the command capsule in the send
> + * WQE (see nvme_rdma_post_send()). If the device cannot provide it,
> + * create the QP without inline data and post the capsule by reference.
> + */
> + attr = init_attr;
> + attr.cap.max_inline_data = sizeof(struct nvme_command);
> + ret = rdma_create_qp(queue->cm_id, dev->pd, &attr);
> + if (ret) {
> + attr = init_attr;
> + ret = rdma_create_qp(queue->cm_id, dev->pd, &attr);
> + }
>
> queue->qp = queue->cm_id->qp;
> + queue->max_inline_data = ret ? 0 : attr.cap.max_inline_data;
> return ret;
> }
>
> @@ -1641,6 +1654,17 @@ static int nvme_rdma_post_send(struct nvme_rdma_queue *queue,
> wr.opcode = IB_WR_SEND;
> wr.send_flags = IB_SEND_SIGNALED;
>
> + /*
> + * Post a capsule without in-capsule data inline if it fits in the
> + * granted inline size, so the HCA does not have to DMA-read it from
> + * host memory. The CPU copies inline data from a kernel virtual
> + * address, so point the SGE at qe->data.
> + */
> + if (num_sge == 1 && sge->length <= queue->max_inline_data) {
> + sge->addr = (uintptr_t)qe->data;
> + wr.send_flags |= IB_SEND_INLINE;
> + }
> +
> if (first)
> first->next = ≀
> else
> --
> 2.56.0
>
---end quoted text---
prev parent reply other threads:[~2026-10-28 14:50 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 12:48 [PATCH 0/1] nvme-rdma: post the command capsule inline when it fits Andrei-Alexandru Bleortu
2026-10-15 12:48 ` [PATCH 1/1] " Andrei-Alexandru Bleortu
2026-10-28 14:49 ` Christoph Hellwig [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=20261028144951.GA14583@lst.de \
--to=hch@lst.de \
--cc=axboe@kernel.dk \
--cc=kbusch@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=linux-rdma@vger.kernel.org \
--cc=me@andrei-z.com \
--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.