From f0b7a6e7d1c9a5df607ba0c628c58ae701b5b584 Mon Sep 17 00:00:00 2001 From: Alexey Marchuk Date: Tue, 16 Jul 2019 06:11:30 +0000 Subject: [PATCH] rdma: fix possible double free on qpair destruction Update rqpair->last_wqe_reached in the context of thread that owns qpair's poll group to avoid possible double free This patch fixes #858 Change-Id: If5422944b7928c2cc05af528fbcc4482aeef22df Signed-off-by: Alexey Marchuk Signed-off-by: Sasha Kotchubievsky Signed-off-by: Evgenii Kochetov Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/462012 Tested-by: SPDK CI Jenkins Reviewed-by: Darek Stojaczyk Reviewed-by: Lorne Li Reviewed-by: Ben Walker Reviewed-by: Shuhei Matsumoto --- lib/nvmf/rdma.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index 2b98dc99a..72c3bbf50 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -2730,6 +2730,15 @@ static const char *CM_EVENT_STR[] = { }; #endif /* DEBUG */ +static void +nvmf_rdma_handle_last_wqe_reached(void *ctx) +{ + struct spdk_nvmf_rdma_qpair *rqpair = ctx; + rqpair->last_wqe_reached = true; + + nvmf_rdma_destroy_drained_qpair(rqpair); +} + static void spdk_nvmf_process_cm_event(struct spdk_nvmf_transport *transport, new_qpair_fn cb_fn) { @@ -2838,14 +2847,13 @@ spdk_nvmf_process_ib_event(struct spdk_nvmf_rdma_device *device) case IBV_EVENT_QP_LAST_WQE_REACHED: /* This event only occurs for shared receive queues. */ rqpair = event.element.qp->qp_context; - rqpair->last_wqe_reached = true; - SPDK_DEBUGLOG(SPDK_LOG_RDMA, "Last WQE reached event received for rqpair %p\n", rqpair); /* This must be handled on the polling thread if it exists. Otherwise the timeout will catch it. */ if (rqpair->qpair.group) { - spdk_thread_send_msg(rqpair->qpair.group->thread, nvmf_rdma_destroy_drained_qpair, rqpair); + spdk_thread_send_msg(rqpair->qpair.group->thread, nvmf_rdma_handle_last_wqe_reached, rqpair); } else { SPDK_ERRLOG("Unable to destroy the qpair %p since it does not have a poll group.\n", rqpair); + rqpair->last_wqe_reached = true; } break;