lib/nvme: Fix aborting queued abort requests at controller reset or destruct

ctrlr->outstanding_aborts is counted only for submitted abort requests.
However ctrlr->outstanding_aborts had been decremented for queued
abort requests by mistake.

Subsequent patches will use parent-children for abort requests but
nvme_free_request() is not aware of such relationship.

Queued abort requests had not been canceled or aborted when controller
was destructed. Retry submitting queued abort requests had been
repeated recursively and had caused stack overflow.

This patch fixes all.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I8ce0ae51ddd5ed3e1e8ac86329c8bdb7a9236b2f
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2555
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Michael Haeuptle <michaelhaeuptle@gmail.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Shuhei Matsumoto 2020-05-21 08:59:16 +09:00 committed by Tomasz Zawadzki
parent 5cbc1d5cae
commit 5322f30787
2 changed files with 25 additions and 7 deletions

View File

@ -1156,12 +1156,28 @@ error:
return rc;
}
static void
nvme_ctrlr_abort_queued_aborts(struct spdk_nvme_ctrlr *ctrlr)
{
struct nvme_request *req, *tmp;
struct spdk_nvme_cpl cpl = {};
cpl.status.sc = SPDK_NVME_SC_ABORTED_SQ_DELETION;
cpl.status.sct = SPDK_NVME_SCT_GENERIC;
STAILQ_FOREACH_SAFE(req, &ctrlr->queued_aborts, stailq, tmp) {
STAILQ_REMOVE_HEAD(&ctrlr->queued_aborts, stailq);
nvme_complete_request(req->cb_fn, req->cb_arg, req->qpair, req, &cpl);
nvme_free_request(req);
}
}
int
spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr)
{
int rc = 0;
struct spdk_nvme_qpair *qpair;
struct nvme_request *req, *tmp;
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
@ -1180,12 +1196,8 @@ spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr)
SPDK_NOTICELOG("resetting controller\n");
/* Free all of the queued abort requests */
STAILQ_FOREACH_SAFE(req, &ctrlr->queued_aborts, stailq, tmp) {
STAILQ_REMOVE_HEAD(&ctrlr->queued_aborts, stailq);
nvme_free_request(req);
ctrlr->outstanding_aborts--;
}
/* Abort all of the queued abort requests */
nvme_ctrlr_abort_queued_aborts(ctrlr);
nvme_transport_admin_qpair_abort_aers(ctrlr->adminq);
@ -2832,6 +2844,8 @@ nvme_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr)
ctrlr->is_destructed = true;
spdk_nvme_qpair_process_completions(ctrlr->adminq, 0);
nvme_ctrlr_abort_queued_aborts(ctrlr);
nvme_transport_admin_qpair_abort_aers(ctrlr->adminq);
TAILQ_FOREACH_SAFE(qpair, &ctrlr->active_io_qpairs, tailq, tmp) {

View File

@ -570,6 +570,10 @@ nvme_ctrlr_retry_queued_abort(struct spdk_nvme_ctrlr *ctrlr)
struct nvme_request *next, *tmp;
int rc;
if (ctrlr->is_resetting || ctrlr->is_destructed) {
return;
}
STAILQ_FOREACH_SAFE(next, &ctrlr->queued_aborts, stailq, tmp) {
STAILQ_REMOVE_HEAD(&ctrlr->queued_aborts, stailq);
ctrlr->outstanding_aborts++;