diff options
| author | Xixin Liu <liuxixin@kylinos.cn> | 2026-08-13 14:42:01 +0800 |
|---|---|---|
| committer | Keith Busch <kbusch@kernel.org> | 2026-08-19 07:52:05 -0700 |
| commit | fb1ed67788e21832b614c23767a088c08cfdd2f2 (patch) | |
| tree | 96a92907f172110b81e7cd68b71d2117b868b294 | |
| parent | 58e7c13c8f0468bdf7e10151d3fb556c6015ab2e (diff) | |
| download | linux-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.c | 15 |
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); |
