From 034d7cc9d7a92604ae68ce161ed93092c83d180f Mon Sep 17 00:00:00 2001 From: Michael Haeuptle Date: Wed, 28 Oct 2020 14:09:47 +0000 Subject: [PATCH] nvmf: Fixes double triggering of association timer Fixes issue #1635. Under rare circumstances, the CC.en and CC.shn are both set which then results in setting the association timer twice. This scenario was observed during hot plug testing when the initiator tries to reset the subsystem that contains the removed device. The end result is that when the ctrlr is destructed, then one of the timers can still fire and access freed memory. Signed-off-by: Michael Haeuptle Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4935 (master) (cherry picked from commit 4409007906b14d771f614b5b5479837191b49206) Change-Id: Ie5880ab325a28f19361f73712bdeb5b58894ee68 Signed-off-by: Tomasz Zawadzki Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4957 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Michael Haeuptle Reviewed-by: Shuhei Matsumoto --- lib/nvmf/ctrlr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index c0b691aea..31ed06670 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -814,6 +814,10 @@ nvmf_ctrlr_cc_shn_done(struct spdk_io_channel_iter *i, int status) /* 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 */ + if (ctrlr->association_timer) { + SPDK_DEBUGLOG(nvmf, "Association timer already set\n"); + nvmf_ctrlr_stop_association_timer(ctrlr); + } ctrlr->association_timer = SPDK_POLLER_REGISTER(nvmf_ctrlr_association_remove, ctrlr, ctrlr->admin_qpair->transport->opts.association_timeout * 1000); } @@ -834,6 +838,10 @@ nvmf_ctrlr_cc_reset_done(struct spdk_io_channel_iter *i, int status) /* 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 */ + if (ctrlr->association_timer) { + SPDK_DEBUGLOG(nvmf, "Association timer already set\n"); + nvmf_ctrlr_stop_association_timer(ctrlr); + } ctrlr->association_timer = SPDK_POLLER_REGISTER(nvmf_ctrlr_association_remove, ctrlr, ctrlr->admin_qpair->transport->opts.association_timeout * 1000); }