Skip to content

Commit eb1bd24

Browse files
Max GurtovoyChristoph Hellwig
authored andcommitted
nvme-rdma: fix memory leak during queue allocation
In case nvme_rdma_wait_for_cm timeout expires before we get an established or rejected event (rdma_connect succeeded) from rdma_cm, we end up with leaking the ib transport resources for dedicated queue. This scenario can easily reproduced using traffic test during port toggling. Also, in order to protect from parallel ib queue destruction, that may be invoked from different context's, introduce new flag that stands for transport readiness. While we're here, protect also against a situation that we can receive rdma_cm events during ib queue destruction. Signed-off-by: Max Gurtovoy <maxg@mellanox.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent f41725b commit eb1bd24

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

drivers/nvme/host/rdma.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct nvme_rdma_request {
7777
enum nvme_rdma_queue_flags {
7878
NVME_RDMA_Q_ALLOCATED = 0,
7979
NVME_RDMA_Q_LIVE = 1,
80+
NVME_RDMA_Q_TR_READY = 2,
8081
};
8182

8283
struct nvme_rdma_queue {
@@ -390,12 +391,23 @@ nvme_rdma_find_get_device(struct rdma_cm_id *cm_id)
390391

391392
static void nvme_rdma_destroy_queue_ib(struct nvme_rdma_queue *queue)
392393
{
393-
struct nvme_rdma_device *dev = queue->device;
394-
struct ib_device *ibdev = dev->dev;
394+
struct nvme_rdma_device *dev;
395+
struct ib_device *ibdev;
396+
397+
if (!test_and_clear_bit(NVME_RDMA_Q_TR_READY, &queue->flags))
398+
return;
399+
400+
dev = queue->device;
401+
ibdev = dev->dev;
395402

396403
ib_mr_pool_destroy(queue->qp, &queue->qp->rdma_mrs);
397404

398-
rdma_destroy_qp(queue->cm_id);
405+
/*
406+
* The cm_id object might have been destroyed during RDMA connection
407+
* establishment error flow to avoid getting other cma events, thus
408+
* the destruction of the QP shouldn't use rdma_cm API.
409+
*/
410+
ib_destroy_qp(queue->qp);
399411
ib_free_cq(queue->ib_cq);
400412

401413
nvme_rdma_free_ring(ibdev, queue->rsp_ring, queue->queue_size,
@@ -463,6 +475,8 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
463475
goto out_destroy_ring;
464476
}
465477

478+
set_bit(NVME_RDMA_Q_TR_READY, &queue->flags);
479+
466480
return 0;
467481

468482
out_destroy_ring:
@@ -529,6 +543,7 @@ static int nvme_rdma_alloc_queue(struct nvme_rdma_ctrl *ctrl,
529543

530544
out_destroy_cm_id:
531545
rdma_destroy_id(queue->cm_id);
546+
nvme_rdma_destroy_queue_ib(queue);
532547
return ret;
533548
}
534549

0 commit comments

Comments
 (0)