summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXixin Liu <liuxixin@kylinos.cn>2026-08-19 14:30:00 +0800
committerKeith Busch <kbusch@kernel.org>2026-08-19 07:46:18 -0700
commitd61828199c6cb4b76d48403c77023cd4bb9d09fc (patch)
treef75c168615366eb0b07f4740c0990f0e60451129
parent3838e80fcfb32e62baffb63c6dc0a60153665a4d (diff)
downloadlinux-d61828199c6cb4b76d48403c77023cd4bb9d09fc.tar.gz
linux-d61828199c6cb4b76d48403c77023cd4bb9d09fc.zip
nvme-rdma: fix -EIO cleanup order in queue_rq
On -EIO, the RDMA queue_rq path reports a host path error and then still cleans up the command and unmaps the SQE DMA. The path error helper completes the request, so that is double cleanup and DMA unmap after the request is already complete. Unmap the SQE first, then report the host path error. Skip the outer command cleanup on that path. Fixes: 62eca39722fd ("nvme-rdma: handle nvme_rdma_post_send failures better") Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Xixin Liu <liuxixin@kylinos.cn> Signed-off-by: Keith Busch <kbusch@kernel.org>
-rw-r--r--drivers/nvme/host/rdma.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 01743ae01466..29ecbe71bb2e 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -2034,7 +2034,7 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,
struct ib_device *dev;
bool queue_ready = test_bit(NVME_RDMA_Q_LIVE, &queue->flags);
blk_status_t ret;
- int err;
+ int err = 0;
WARN_ON_ONCE(rq->tag < 0);
@@ -2090,16 +2090,18 @@ 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);
- else if (err == -ENOMEM || err == -EAGAIN)
- ret = BLK_STS_RESOURCE;
- else
- ret = BLK_STS_IOERR;
- nvme_cleanup_cmd(rq);
+ if (err != -EIO) {
+ nvme_cleanup_cmd(rq);
+ if (err == -ENOMEM || err == -EAGAIN)
+ ret = BLK_STS_RESOURCE;
+ else
+ ret = BLK_STS_IOERR;
+ }
unmap_qe:
ib_dma_unmap_single(dev, req->sqe.dma, sizeof(struct nvme_command),
DMA_TO_DEVICE);
+ if (err == -EIO)
+ return nvme_host_path_error(rq);
return ret;
}