Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* Re: [PATCH 1/1] nvme-rdma: post the command capsule inline when it fits
       [not found] ` <20261015124823.2962700-2-me@andrei-z.com>
@ 2026-10-28 14:49   ` Christoph Hellwig
  0 siblings, 0 replies; only message in thread
From: Christoph Hellwig @ 2026-10-28 14:49 UTC (permalink / raw)
  To: Andrei-Alexandru Bleortu
  Cc: Keith Busch, Jens Axboe, Christoph Hellwig, Sagi Grimberg,
	linux-nvme, linux-rdma

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 = &wr;
>  	else
> -- 
> 2.56.0
> 
---end quoted text---

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-28 14:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20261015124823.2962700-1-me@andrei-z.com>
     [not found] ` <20261015124823.2962700-2-me@andrei-z.com>
2026-10-28 14:49   ` [PATCH 1/1] nvme-rdma: post the command capsule inline when it fits Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox