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. Start the request only after the mapping succeeds, as nvme-pci and nvme-tcp do. A hard status from ->queue_rq is completed by blk-mq itself, skipping nvme_mpath_end_request(), so the multipath I/O accounting leaks -- today for -EINVAL, and now for BLK_STS_P2PDMA. Fixes: 23528aa3320a ("nvme: enable PCI P2PDMA support for RDMA transport") Cc: stable@vger.kernel.org # v7.1: requires BLK_STS_P2PDMA and the ib_dma_map_sgtable_attrs() conversion Assisted-by: Claude:claude-fable-5 Signed-off-by: Mykola Marzhan Reviewed-by: Logan Gunthorpe --- drivers/nvme/host/rdma.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 63830334c73e..c38d949502b7 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1486,10 +1486,8 @@ static int nvme_rdma_dma_map_req(struct ib_device *ibdev, struct request *rq, .orig_nents = req->data_sgl.nents, }; ret = ib_dma_map_sgtable_attrs(ibdev, &sgt, rq_dma_dir(rq), 0); - if (unlikely(ret)) { - ret = -EIO; + if (unlikely(ret)) goto out_free_table; - } *count = sgt.nents; if (blk_integrity_rq(rq)) { @@ -1511,10 +1509,8 @@ static int nvme_rdma_dma_map_req(struct ib_device *ibdev, struct request *rq, .orig_nents = req->metadata_sgl->nents, }; ret = ib_dma_map_sgtable_attrs(ibdev, &sgt, rq_dma_dir(rq), 0); - if (unlikely(ret)) { - ret = -EIO; + if (unlikely(ret)) goto out_free_pi_table; - } *pi_count = sgt.nents; } @@ -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 || @@ -2051,6 +2045,8 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, goto err; } + nvme_start_request(rq); + 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, ret = nvme_host_path_error(rq); else if (err == -ENOMEM || err == -EAGAIN) ret = BLK_STS_RESOURCE; + /* 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); -- 2.52.0