nvmf: association timer triggered on shutdown

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 <jacek.kalwas@intel.com>
Signed-off-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Change-Id: I4734600067fd4b7306b46f1325fdd5031e81c079
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2984
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Jacek Kalwas 2020-06-21 09:47:34 +02:00 committed by Tomasz Zawadzki
parent b70fc69b32
commit 71cd42e139
4 changed files with 50 additions and 0 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}