[PATCH 1/6] blk-mq-dma: restore BLK_STS_TARGET for unsupported P2P transfers

From: Mykola Marzhan

Date: Sat Jul 18 2026 - 12:27:25 EST


Commit 91fb2b6052f7 ("nvme-pci: convert to using dma_map_sgtable()")
deliberately mapped unsupported P2PDMA transfers to BLK_STS_TARGET,
matching dma_map_sgtable()'s -EREMOTEIO: "When this happens, return
BLK_STS_TARGET so the request isn't retried." The conversion to
blk_rq_dma_map silently changed the status to BLK_STS_INVAL, which
regresses two consumers:

- md/raid1 and raid10 ignore BLK_STS_INVAL leg failures
(commit f7b24c7b41f2 ("md/raid1,raid10: don't fail devices for
invalid IO errors"), where it means a request-shaped error that
fails identically on every member). Since commit 02666132403a
("md: propagate BLK_FEAT_PCI_P2PDMA from member devices to RAID device")
P2PDMA bios reach md arrays: a peer-memory write to a member the
peer cannot reach is counted as written, the master bio reports
success, mirrors silently diverge, and on a topology where no
member is reachable the write reports success with zero copies on
stable storage.

- the failure's classification flips: for direct NVMe consumers
(nvme advertises BLK_FEAT_PCI_P2PDMA) the mapping failure has
surfaced as EINVAL instead of the documented -EREMOTEIO since
v6.17, and blk_path_error(BLK_STS_INVAL) is true, so a stacking
consumer would treat it as a retryable path error (dm-mpath is
the only in-tree blk_path_error() caller; P2P bios cannot
currently reach it, but the classification is wrong on its face).

Restore BLK_STS_TARGET. md then routes an unreachable leg through
its per-device error handling (badblocks, WantReplacement, mirror
retry for reads); a follow-up patch teaches raid1/raid10 to handle
mapping failures without the retry storms that machinery was built
around.

Fixes: 858299dc6160 ("block: add scatterlist-less DMA mapping helpers")
Fixes: 7ce3c1dd78fc ("nvme-pci: convert the data mapping to blk_rq_dma_map")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Mykola Marzhan <mykola@xxxxxxxxxxx>
---
block/blk-mq-dma.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/block/blk-mq-dma.c b/block/blk-mq-dma.c
index bfdb9ed70741..2eed06bfe791 100644
--- a/block/blk-mq-dma.c
+++ b/block/blk-mq-dma.c
@@ -190,7 +190,15 @@ static bool blk_dma_map_iter_start(struct request *req, struct device *dma_dev,
case PCI_P2PDMA_MAP_NONE:
break;
default:
- iter->status = BLK_STS_INVAL;
+ /*
+ * P2P transfers that the mapping layer cannot support
+ * report BLK_STS_TARGET, matching dma_map_sgtable()'s
+ * -EREMOTEIO and the pre-blk_rq_dma_map nvme behavior:
+ * the failure is a property of this device pairing, so
+ * it must not be retried on another path (blk_path_error)
+ * nor be mistaken for an invalid request.
+ */
+ iter->status = BLK_STS_TARGET;
return false;
}

--
2.43.0