summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXixin Liu <liuxixin@kylinos.cn>2026-08-13 14:42:01 +0800
committerKeith Busch <kbusch@kernel.org>2026-08-19 07:52:05 -0700
commitfb1ed67788e21832b614c23767a088c08cfdd2f2 (patch)
tree96a92907f172110b81e7cd68b71d2117b868b294
parent58e7c13c8f0468bdf7e10151d3fb556c6015ab2e (diff)
downloadlinux-fb1ed67788e21832b614c23767a088c08cfdd2f2.tar.gz
linux-fb1ed67788e21832b614c23767a088c08cfdd2f2.zip
nvmet-rdma: fix queue leak when connect backlog is exceeded
When pending disconnecting queues exceed the backlog limit, the connect path only drops the device reference and leaks the newly allocated queue and its IB resources. Fixes: badc53620fe8 ("nvme: target: rdma: fix ndev refcount leak on queue connect") 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/target/rdma.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index de5a88fbb233..542138fd669f 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -1627,19 +1627,13 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
mutex_unlock(&nvmet_rdma_queue_mutex);
if (pending > NVMET_RDMA_BACKLOG) {
ret = NVME_SC_CONNECT_CTRL_BUSY;
- goto put_device;
+ goto free_queue;
}
}
ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn);
- if (ret) {
- /*
- * Don't destroy the cm_id in free path, as we implicitly
- * destroy the cm_id here with non-zero ret code.
- */
- queue->cm_id = NULL;
+ if (ret)
goto free_queue;
- }
mutex_lock(&nvmet_rdma_queue_mutex);
list_add_tail(&queue->queue_list, &nvmet_rdma_queue_list);
@@ -1648,6 +1642,11 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
return 0;
free_queue:
+ /*
+ * Don't destroy the cm_id in free path, as we implicitly
+ * destroy the cm_id here with non-zero ret code.
+ */
+ queue->cm_id = NULL;
nvmet_rdma_free_queue(queue);
put_device:
kref_put(&ndev->ref, nvmet_rdma_free_dev);