From a59aff1ad928fc1722345d022e332c6d516f6df9 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Tue, 19 Oct 2021 18:12:09 +0800 Subject: [PATCH] nvmf: only change CSTS RDY and SHN after no connected IO queues When doing controller reset and shutdown, we may change the CSTS.RDY and CSTS.SHN even there are pending IOs in the IO queues, so here we add a timer in the reset and shutdown callback, it will change the status when there are no connected IO queues. Fix #2199. Change-Id: I3a54d30b257973661b269ad5e37637490f9390f4 Signed-off-by: Changpeng Liu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9908 Reviewed-by: Ben Walker Reviewed-by: Aleksey Marchuk Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins --- lib/nvmf/ctrlr.c | 34 ++++++++++++++++++++++++++++------ lib/nvmf/nvmf_internal.h | 2 ++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 154a1b2e3..fe0c23e81 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -930,14 +930,22 @@ nvmf_ctrlr_association_remove(void *ctx) return SPDK_POLLER_BUSY; } -static void -nvmf_ctrlr_cc_reset_shn_done(struct spdk_io_channel_iter *i, int status) +static int +_nvmf_ctrlr_cc_reset_shn_done(void *ctx) { - struct spdk_nvmf_ctrlr *ctrlr = spdk_io_channel_iter_get_ctx(i); + struct spdk_nvmf_ctrlr *ctrlr = ctx; + uint32_t count; - if (status < 0) { - SPDK_ERRLOG("Fail to disconnect io ctrlr qpairs\n"); - assert(false); + if (ctrlr->cc_timer) { + spdk_poller_unregister(&ctrlr->cc_timer); + } + + count = spdk_bit_array_count_set(ctrlr->qpair_mask); + SPDK_DEBUGLOG(nvmf, "ctrlr %p active queue count %u\n", ctrlr, count); + + if (count > 1) { + ctrlr->cc_timer = SPDK_POLLER_REGISTER(_nvmf_ctrlr_cc_reset_shn_done, ctrlr, 100 * 1000); + return SPDK_POLLER_IDLE; } if (ctrlr->disconnect_is_shn) { @@ -960,6 +968,20 @@ nvmf_ctrlr_cc_reset_shn_done(struct spdk_io_channel_iter *i, int status) ctrlr->association_timeout * 1000); } ctrlr->disconnect_in_progress = false; + return SPDK_POLLER_BUSY; +} + +static void +nvmf_ctrlr_cc_reset_shn_done(struct spdk_io_channel_iter *i, int status) +{ + struct spdk_nvmf_ctrlr *ctrlr = spdk_io_channel_iter_get_ctx(i); + + if (status < 0) { + SPDK_ERRLOG("Fail to disconnect io ctrlr qpairs\n"); + assert(false); + } + + _nvmf_ctrlr_cc_reset_shn_done((void *)ctrlr); } const struct spdk_nvmf_registers * diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 37dd389d1..c07e05880 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -268,6 +268,8 @@ struct spdk_nvmf_ctrlr { struct spdk_poller *association_timer; + struct spdk_poller *cc_timer; + bool dif_insert_or_strip; bool in_destruct; bool disconnect_in_progress;