nvme: Call ctrlr_disconnect_done() after qpair_process_comletions() returns -ENXIO

Add a new flag is_disconnecting to struct spdk_nvme_ctrlr.

Separate calling nvme_ctrlr_disconnect() and nvme_ctrlr_disconnect_done()
by using the flag is_disconnecting.

Additionally, change nvme_ctrlr_fail() to skip setting ctrlr->is_failed
to true if ctrlr->is_disconnecting is true.

Change-Id: Ie2c74ba41f120662a30f6198751d07005d23abcf
Signed-off-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11000
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Shuhei Matsumoto 2022-02-21 11:51:07 +09:00 committed by Tomasz Zawadzki
parent 8926303b59
commit df7c2a2253
3 changed files with 26 additions and 8 deletions

View File

@ -1040,6 +1040,11 @@ nvme_ctrlr_fail(struct spdk_nvme_ctrlr *ctrlr, bool hot_remove)
return;
}
if (ctrlr->is_disconnecting) {
NVME_CTRLR_DEBUGLOG(ctrlr, "already disconnecting\n");
return;
}
ctrlr->is_failed = true;
nvme_transport_ctrlr_disconnect_qpair(ctrlr, ctrlr->adminq);
NVME_CTRLR_ERRLOG(ctrlr, "in failed state.\n");
@ -1640,6 +1645,7 @@ nvme_ctrlr_disconnect(struct spdk_nvme_ctrlr *ctrlr)
ctrlr->is_resetting = true;
ctrlr->is_failed = false;
ctrlr->is_disconnecting = true;
NVME_CTRLR_NOTICELOG(ctrlr, "resetting controller\n");
@ -1665,6 +1671,9 @@ nvme_ctrlr_disconnect(struct spdk_nvme_ctrlr *ctrlr)
static void
nvme_ctrlr_disconnect_done(struct spdk_nvme_ctrlr *ctrlr)
{
assert(ctrlr->is_failed == false);
ctrlr->is_disconnecting = false;
/* Doorbell buffer config is invalid during reset */
nvme_ctrlr_free_doorbell_buffer(ctrlr);
@ -1680,13 +1689,9 @@ spdk_nvme_ctrlr_disconnect(struct spdk_nvme_ctrlr *ctrlr)
int rc;
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
rc = nvme_ctrlr_disconnect(ctrlr);
if (rc == 0) {
nvme_ctrlr_disconnect_done(ctrlr);
}
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
return rc;
}
@ -1789,9 +1794,6 @@ spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr)
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
rc = nvme_ctrlr_disconnect(ctrlr);
if (rc == 0) {
nvme_ctrlr_disconnect_done(ctrlr);
}
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
@ -1802,6 +1804,13 @@ spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr)
return rc;
}
while (1) {
rc = spdk_nvme_ctrlr_process_admin_completions(ctrlr);
if (rc == -ENXIO) {
break;
}
}
spdk_nvme_ctrlr_reconnect_async(ctrlr);
while (true) {
@ -4248,6 +4257,10 @@ spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr)
nvme_ctrlr_complete_queued_async_events(ctrlr);
}
if (rc == -ENXIO && ctrlr->is_disconnecting) {
nvme_ctrlr_disconnect_done(ctrlr);
}
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
if (rc < 0) {

View File

@ -887,6 +887,8 @@ struct spdk_nvme_ctrlr {
*/
bool prepare_for_reset;
bool is_disconnecting;
uint16_t max_sges;
uint16_t cntlid;

View File

@ -2794,6 +2794,7 @@ test_nvme_ctrlr_reset(void)
g_ut_nvme_regs.cc.raw = 0;
g_ut_nvme_regs.csts.raw = 0;
g_set_reg_cb = check_en_set_rdy;
g_wait_for_completion_return_val = -ENXIO;
CU_ASSERT(spdk_nvme_ctrlr_reset(&ctrlr) == 0);
g_set_reg_cb = NULL;
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_READY);
@ -2807,6 +2808,8 @@ test_nvme_ctrlr_reset(void)
g_ut_nvme_regs.csts.bits.shst = SPDK_NVME_SHST_COMPLETE;
nvme_ctrlr_destruct(&ctrlr);
g_wait_for_completion_return_val = 0;
}
static uint32_t g_aer_cb_counter;