Commit f0b7a6e7 authored by Alexey Marchuk's avatar Alexey Marchuk Committed by Ben Walker
Browse files

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: default avatarAlexey Marchuk <alexeymar@mellanox.com>
Signed-off-by: default avatarSasha Kotchubievsky <sashakot@mellanox.com>
Signed-off-by: default avatarEvgenii Kochetov <evgeniik@mellanox.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/462012


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: default avatarLorne Li <lorneli@163.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 34cdf61f
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -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;