[PATCH] nvme-rdma: fix -EIO cleanup order in queue_rq

Xixin Liu posted 1 patch 1 month, 2 weeks ago
There is a newer version of this series
drivers/nvme/host/rdma.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
[PATCH] nvme-rdma: fix -EIO cleanup order in queue_rq
Posted by Xixin Liu 1 month, 2 weeks ago
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")
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
---
 drivers/nvme/host/rdma.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 56cd228af1d5..d80b81676527 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -2061,16 +2061,16 @@ 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);
+		ret = (err == -ENOMEM || err == -EAGAIN) ?
+			BLK_STS_RESOURCE : 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;
 }
 
-- 
2.53.0
[PATCH v2 0/1] nvme-rdma: fix -EIO cleanup order in queue_rq
Posted by Xixin Liu 1 month, 1 week ago
Hi,

Thanks Christoph for the if/else readability suggestion on the
RESOURCE versus IOERR branch.

Changes since v1:
- use if/else for RESOURCE versus IOERR as suggested by Christoph
- initialize err to 0 for the shared unmap_qe path

Thanks,
Xixin Liu

---

Xixin Liu (1):
  nvme-rdma: fix -EIO cleanup order in queue_rq

 drivers/nvme/host/rdma.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

-- 
2.53.0
[PATCH v2 1/1] nvme-rdma: fix -EIO cleanup order in queue_rq
Posted by Xixin Liu 1 month, 1 week ago
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")
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
---
 drivers/nvme/host/rdma.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 56cd228af1d5..a1b2c3d4e5f6 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -2005,7 +2005,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);
 
@@ -2061,16 +2061,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;
 }
 
-- 
2.53.0
Re: [PATCH v2 1/1] nvme-rdma: fix -EIO cleanup order in queue_rq
Posted by Keith Busch 1 month, 1 week ago
On Wed, Aug 19, 2026 at 02:30:00PM +0800, Xixin Liu wrote:
> 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.

Thanks, applied to nvme-7.3.
Re: [PATCH v2 1/1] nvme-rdma: fix -EIO cleanup order in queue_rq
Posted by Christoph Hellwig 1 month, 1 week ago
Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>
Re: [PATCH] nvme-rdma: fix -EIO cleanup order in queue_rq
Posted by Christoph Hellwig 1 month, 1 week ago
On Thu, Aug 13, 2026 at 05:45:00PM +0800, Xixin Liu wrote:
> -	nvme_cleanup_cmd(rq);
> +	if (err != -EIO) {
> +		nvme_cleanup_cmd(rq);
> +		ret = (err == -ENOMEM || err == -EAGAIN) ?
> +			BLK_STS_RESOURCE : BLK_STS_IOERR;

Please stick to the much more readable if/else here.