From 71cd42e1397b2b073597903a88c3ef3b0cf96751 Mon Sep 17 00:00:00 2001 From: Jacek Kalwas Date: Sun, 21 Jun 2020 09:47:34 +0200 Subject: [PATCH] nvmf: association timer triggered on shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After CC.EN transitions to ‘0’ (due to shutdown or reset), the association between the host and controller shall be preserved for at least 2 minutes. After this time, the association may be removed if the controller has not been re-enabled. Signed-off-by: Jacek Kalwas Signed-off-by: Darek Stojaczyk Change-Id: I4734600067fd4b7306b46f1325fdd5031e81c079 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2984 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Changpeng Liu --- include/spdk/nvmf.h | 1 + lib/nvmf/ctrlr.c | 45 ++++++++++++++++++++++++++++++++++++++++ lib/nvmf/nvmf_internal.h | 2 ++ lib/nvmf/transport.c | 2 ++ 4 files changed, 50 insertions(+) diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index 91ae484b0..8e18f9c55 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -86,6 +86,7 @@ struct spdk_nvmf_transport_opts { uint32_t sock_priority; int acceptor_backlog; uint32_t abort_timeout_sec; + uint32_t association_timeout; }; struct spdk_nvmf_poll_group_stat { diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 0c20f32d9..aaf15fccf 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -102,6 +102,23 @@ nvmf_ctrlr_stop_keep_alive_timer(struct spdk_nvmf_ctrlr *ctrlr) spdk_poller_unregister(&ctrlr->keep_alive_poller); } +static void +nvmf_ctrlr_stop_association_timer(struct spdk_nvmf_ctrlr *ctrlr) +{ + if (!ctrlr) { + SPDK_ERRLOG("Controller is NULL\n"); + assert(false); + return; + } + + if (ctrlr->association_timer == NULL) { + return; + } + + SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Stop association timer\n"); + spdk_poller_unregister(&ctrlr->association_timer); +} + static void nvmf_ctrlr_disconnect_qpairs_done(struct spdk_io_channel_iter *i, int status) { @@ -403,7 +420,9 @@ _nvmf_ctrlr_destruct(void *ctx) struct spdk_nvmf_reservation_log *log, *log_tmp; nvmf_ctrlr_stop_keep_alive_timer(ctrlr); + nvmf_ctrlr_stop_association_timer(ctrlr); spdk_bit_array_free(&ctrlr->qpair_mask); + TAILQ_FOREACH_SAFE(log, &ctrlr->log_head, link, log_tmp) { TAILQ_REMOVE(&ctrlr->log_head, log, link); free(log); @@ -720,6 +739,25 @@ nvmf_ctrlr_cmd_connect(struct spdk_nvmf_request *req) return _nvmf_ctrlr_connect(req); } +static int +nvmf_ctrlr_association_remove(void *ctx) +{ + struct spdk_nvmf_ctrlr *ctrlr = ctx; + int rc; + + SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Disconnecting host from subsystem %s due to association timeout.\n", + ctrlr->subsys->subnqn); + + rc = spdk_nvmf_qpair_disconnect(ctrlr->admin_qpair, NULL, NULL); + if (rc < 0) { + SPDK_ERRLOG("Fail to disconnect admin ctrlr qpair\n"); + assert(false); + } + + nvmf_ctrlr_stop_association_timer(ctrlr); + return 1; +} + static void nvmf_ctrlr_cc_shn_done(struct spdk_io_channel_iter *i, int status) { @@ -731,6 +769,11 @@ nvmf_ctrlr_cc_shn_done(struct spdk_io_channel_iter *i, int status) } ctrlr->vcprop.csts.bits.shst = SPDK_NVME_SHST_COMPLETE; + + /* After CC.EN transitions to 0 (due to shutdown or reset), the association + * between the host and controller shall be preserved for at least 2 minutes */ + ctrlr->association_timer = SPDK_POLLER_REGISTER(nvmf_ctrlr_association_remove, ctrlr, + ctrlr->admin_qpair->transport->opts.association_timeout); } static void @@ -792,6 +835,8 @@ nvmf_prop_set_cc(struct spdk_nvmf_ctrlr *ctrlr, uint32_t value) if (diff.bits.en) { if (cc.bits.en) { SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Property Set CC Enable!\n"); + nvmf_ctrlr_stop_association_timer(ctrlr); + ctrlr->vcprop.cc.bits.en = 1; ctrlr->vcprop.csts.bits.rdy = 1; } else { diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index f1f3837d5..c5b6704c9 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -231,6 +231,8 @@ struct spdk_nvmf_ctrlr { uint64_t last_keep_alive_tick; struct spdk_poller *keep_alive_poller; + struct spdk_poller *association_timer; + bool dif_insert_or_strip; TAILQ_ENTRY(spdk_nvmf_ctrlr) link; diff --git a/lib/nvmf/transport.c b/lib/nvmf/transport.c index 323af72ff..636cfa223 100644 --- a/lib/nvmf/transport.c +++ b/lib/nvmf/transport.c @@ -44,6 +44,7 @@ #include "spdk/util.h" #define MAX_MEMPOOL_NAME_LENGTH 40 +#define NVMF_TRANSPORT_DEFAULT_ASSOCIATION_TIMEOUT 120000 /* ms */ struct nvmf_transport_ops_list_element { struct spdk_nvmf_transport_ops ops; @@ -499,6 +500,7 @@ spdk_nvmf_transport_opts_init(const char *transport_name, return false; } + opts->association_timeout = NVMF_TRANSPORT_DEFAULT_ASSOCIATION_TIMEOUT; ops->opts_init(opts); return true; }