From caa06154bdf7518deea7872c8c075d4202a279c9 Mon Sep 17 00:00:00 2001 From: Seth Howell Date: Mon, 7 Jan 2019 11:48:19 -0700 Subject: [PATCH] rdma: fix the poll_group_create error paths. It was possible to leak pollers if we had multiple devices in the transport. The new err_exit path fixes this. Change-Id: Iafd5643c67fae741113f10afe761af1988cb6a9b Signed-off-by: Seth Howell Reviewed-on: https://review.gerrithub.io/c/439419 Tested-by: SPDK CI Jenkins Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Shuhei Matsumoto Reviewed-by: Darek Stojaczyk Reviewed-by: Ben Walker --- lib/nvmf/rdma.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index f851bcbc4..090e4e161 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -2373,7 +2373,7 @@ spdk_nvmf_rdma_poll_group_create(struct spdk_nvmf_transport *transport) { struct spdk_nvmf_rdma_transport *rtransport; struct spdk_nvmf_rdma_poll_group *rgroup; - struct spdk_nvmf_rdma_poller *poller; + struct spdk_nvmf_rdma_poller *poller, *tpoller; struct spdk_nvmf_rdma_device *device; rtransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_rdma_transport, transport); @@ -2390,9 +2390,7 @@ spdk_nvmf_rdma_poll_group_create(struct spdk_nvmf_transport *transport) poller = calloc(1, sizeof(*poller)); if (!poller) { SPDK_ERRLOG("Unable to allocate memory for new RDMA poller\n"); - free(rgroup); - pthread_mutex_unlock(&rtransport->lock); - return NULL; + goto err_exit; } poller->device = device; @@ -2404,9 +2402,7 @@ spdk_nvmf_rdma_poll_group_create(struct spdk_nvmf_transport *transport) if (!poller->cq) { SPDK_ERRLOG("Unable to create completion queue\n"); free(poller); - free(rgroup); - pthread_mutex_unlock(&rtransport->lock); - return NULL; + goto err_exit; } TAILQ_INSERT_TAIL(&rgroup->pollers, poller, link); @@ -2414,6 +2410,19 @@ spdk_nvmf_rdma_poll_group_create(struct spdk_nvmf_transport *transport) pthread_mutex_unlock(&rtransport->lock); return &rgroup->group; + +err_exit: + TAILQ_FOREACH_SAFE(poller, &rgroup->pollers, link, tpoller) { + TAILQ_REMOVE(&rgroup->pollers, poller, link); + if (poller->cq) { + ibv_destroy_cq(poller->cq); + } + free(poller); + } + + free(rgroup); + pthread_mutex_unlock(&rtransport->lock); + return NULL; } static void