From a28a5c8ff7d3aa2dce6a9443307f14e20eff481a Mon Sep 17 00:00:00 2001 From: Seth Howell Date: Fri, 13 Jul 2018 09:41:22 -0700 Subject: [PATCH] nvmf: ensure that destroying qpairs have a state_cb It appears that we can get caught in a loop when shutting down a subsystem if there is a qpair that has been moved to the deactivating state due to the target shutting down early. These qpairs don't have a state cb and won't ever be destroyed or removed from the global list. Change-Id: I4f9ed774a94e0e2c7ff7bfa3af1776b38a787035 Signed-off-by: Seth Howell Reviewed-on: https://review.gerrithub.io/419269 Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto Reviewed-by: Ben Walker Tested-by: SPDK CI Jenkins --- lib/nvmf/nvmf.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index ece31ddb7..e00495a11 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -669,6 +669,17 @@ _spdk_nvmf_qpair_deactivate(void *ctx) struct nvmf_qpair_disconnect_ctx *qpair_ctx = ctx; struct spdk_nvmf_qpair *qpair = qpair_ctx->qpair; + /* Check for outstanding I/O */ + if (!TAILQ_EMPTY(&qpair->outstanding)) { + if (qpair->state_cb != NULL) { + qpair->state_cb = _spdk_nvmf_qpair_destroy; + qpair->state_cb_arg = qpair_ctx; + } else { + free(qpair_ctx); + } + return; + } + if (qpair->state == SPDK_NVMF_QPAIR_DEACTIVATING || qpair->state == SPDK_NVMF_QPAIR_INACTIVE) { /* This can occur if the connection is killed by the target, @@ -684,13 +695,6 @@ _spdk_nvmf_qpair_deactivate(void *ctx) assert(qpair->state == SPDK_NVMF_QPAIR_ACTIVE); qpair->state = SPDK_NVMF_QPAIR_DEACTIVATING; - /* Check for outstanding I/O */ - if (!TAILQ_EMPTY(&qpair->outstanding)) { - qpair->state_cb = _spdk_nvmf_qpair_destroy; - qpair->state_cb_arg = qpair_ctx; - return; - } - _spdk_nvmf_qpair_destroy(qpair_ctx, 0); }