Linux RAID subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Mykola Marzhan" <mykola@meshstor.io>
Cc: linux-raid@vger.kernel.org, yukuai@fygo.io, linux-pci@vger.kernel.org
Subject: Re: [PATCH v5 10/10] nvme-rdma: return BLK_STS_P2PDMA for unsupported P2P transfers
Date: Thu, 23 Jul 2026 21:19:39 +0000	[thread overview]
Message-ID: <20260723211939.8EB041F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260723204206.76930-11-mykola@meshstor.io>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [High] Modifying the PI metadata buffer via nvme_start_request() after it has been mapped for DMA causes cache coherency issues on non-coherent architectures.

Pre-existing issues:
- [High] Accessing the block request and its associated PDU after being freed on the error handling path when mapping or post_send fails with -EIO.
- [High] Returning BLK_STS_RESOURCE after the request has been started triggers kernel warnings and false timeouts.
- [Medium] Returning a hard error from queue_rq after calling nvme_start_request() bypasses nvme_mpath_end_request(), leaking the nr_active counter.
--

--- Patch [10]: [PATCH v5 10/10] nvme-rdma: return BLK_STS_P2PDMA for unsupported P2P transfers ---
commit 2111f8ba9b5738dc4d1ef4e08339058c75231ebd
Author: Mykola Marzhan <mykola@meshstor.io>

nvme-rdma: return BLK_STS_P2PDMA for unsupported P2P transfers

> A P2P transfer the PCIe topology cannot route fails DMA mapping
> with -EREMOTEIO.  nvme-rdma folds every mapping error into -EIO, a
> retryable host-path error: multipath requeues the I/O forever, a
> single path burns its whole retry budget.
> 
> Propagate the real error code and return the unroutable case as the
> non-retryable BLK_STS_P2PDMA.  As in nvme-pci, -ENOMEM now requeues
> (BLK_STS_RESOURCE) and -EINVAL fails (BLK_STS_IOERR); -EIO stays a
> retryable host-path error.  While at it, start the request only
> after mapping succeeds -- nvme-pci's order -- and ratelimit the
> map-failure message.

> diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
> index 63830334c73e2..2f50509a7a616 100644
> --- a/drivers/nvme/host/rdma.c
> +++ b/drivers/nvme/host/rdma.c
> [ ... ]
> @@ -2033,8 +2029,6 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,
>  	if (ret)
>  		goto unmap_qe;
>  
> -	nvme_start_request(rq);
> -
>  	if (IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) &&
>  	    queue->pi_support &&
>  	    (c->common.opcode == nvme_cmd_write ||
> @@ -2046,11 +2040,13 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,
>  
>  	err = nvme_rdma_map_data(queue, rq, c);
>  	if (unlikely(err < 0)) {
> -		dev_err(queue->ctrl->ctrl.device,
> -			     "Failed to map data (%d)\n", err);
> +		dev_err_ratelimited(queue->ctrl->ctrl.device,
> +				    "Failed to map data (%d)\n", err);
>  		goto err;
>  	}
>  
> +	nvme_start_request(rq);

[Severity: High]
Since the patch moves nvme_start_request() to execute after
nvme_rdma_map_data() has mapped the metadata buffer for streaming DMA, can this
cause cache coherency issues on non-coherent architectures?

nvme_start_request() invokes blk_integrity_prepare(), which writes to the PI
tags directly in the CPU cache. 

Because this now happens after the memory is mapped, those modifications might
not be synced to main memory, causing the RDMA NIC to read stale PI tags and
leading to silent data corruption and I/O failures.

> +
>  	sqe->cqe.done = nvme_rdma_send_done;
>  
>  	ib_dma_sync_single_for_device(dev, sqe->dma,
> [ ... ]
> @@ -2070,6 +2066,9 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,
>  
>  err_unmap:
>  	nvme_rdma_unmap_data(queue, rq);
>  err:
>  	if (err == -EIO)
>  		ret = nvme_host_path_error(rq);

[Severity: High]
This is a pre-existing issue, but does this lead to a use-after-free when
nvme_rdma_map_data() or nvme_rdma_post_send() fails with -EIO?

nvme_host_path_error() synchronously completes the request via
blk_mq_set_request_complete() and __nvme_complete_rq(). This frees the request
and its PDU back to the tag allocator, where it can be immediately reallocated.

The code then falls through and accesses the freed request by calling
nvme_cleanup_cmd(rq) and reading req->sqe.dma during ib_dma_unmap_single().

>  	else if (err == -ENOMEM || err == -EAGAIN)
>  		ret = BLK_STS_RESOURCE;

[Severity: High]
This is a pre-existing issue, but does returning BLK_STS_RESOURCE here cause
false I/O timeouts?

At this point, nvme_start_request() has already been called, placing the
request in the MQ_RQ_IN_FLIGHT state and starting its timeout timer. 

When returning BLK_STS_RESOURCE, the block layer requeues the request without
reverting its state to MQ_RQ_IDLE. This leaves the timer ticking while the
request is on the dispatch queue, eventually triggering a false timeout and
controller reset.

> +	/* Peer memory unreachable from this device: don't retry. */
> +	else if (err == -EREMOTEIO)
> +		ret = BLK_STS_P2PDMA;
>  	else
>  		ret = BLK_STS_IOERR;
>  	nvme_cleanup_cmd(rq);

[Severity: Medium]
This is a pre-existing issue, but does returning a hard error here leak the
multipath nr_active counter?

When a hard error is returned to the block layer from nvme_rdma_queue_rq(),
it directly completes the request via blk_mq_end_request(), bypassing the
driver's .complete callback. 

Since nvme_start_request() was already called and incremented the multipath
nr_active counter, bypassing the completion callback means
nvme_mpath_end_request() is never invoked to balance the counter.

>  unmap_qe:
>  	ib_dma_unmap_single(dev, req->sqe.dma, sizeof(struct nvme_command),
>  			    DMA_TO_DEVICE);
>  	return ret;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260723204206.76930-1-mykola@meshstor.io?part=10

      reply	other threads:[~2026-07-23 21:19 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23 20:41 [PATCH v5 00/10] block,md,nvme: correct handling of unsupported P2PDMA transfers Mykola Marzhan
2026-07-23 20:41 ` [PATCH v5 01/10] block: add BLK_STS_P2PDMA for unsupported peer-to-peer transfers Mykola Marzhan
2026-07-23 20:51   ` sashiko-bot
2026-07-23 20:41 ` [PATCH v5 02/10] md: ensure REQ_NOMERGE is set on P2PDMA bios Mykola Marzhan
2026-07-23 20:51   ` sashiko-bot
2026-07-23 20:41 ` [PATCH v5 03/10] md/raid1: serialize non-write-behind writes on CollisionCheck rdevs Mykola Marzhan
2026-07-23 21:04   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 04/10] md/raid1: don't use write-behind for P2PDMA bios Mykola Marzhan
2026-07-23 21:01   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 05/10] md/raid1,raid10: factor out raid1_write_error() helper Mykola Marzhan
2026-07-23 20:54   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 06/10] md/raid1,raid10: keep REQ_NOMERGE on narrow_write_error() retry clones Mykola Marzhan
2026-07-23 21:05   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 07/10] md/raid1,raid10: skip futile retries on P2PDMA mapping failures Mykola Marzhan
2026-07-23 21:09   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 08/10] md/raid1,raid10: set IO_BLOCKED in case of BLK_STS_P2PDMA Mykola Marzhan
2026-07-23 21:13   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 09/10] nvme-rdma: use ib_dma_map_sgtable_attrs() Mykola Marzhan
2026-07-23 21:09   ` sashiko-bot
2026-07-23 20:42 ` [PATCH v5 10/10] nvme-rdma: return BLK_STS_P2PDMA for unsupported P2P transfers Mykola Marzhan
2026-07-23 21:19   ` sashiko-bot [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=20260723211939.8EB041F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=mykola@meshstor.io \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=yukuai@fygo.io \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox