lib/nvme: Do not submit queued aborts if adminq is in failed state.

With RDMA, the admin poller can experience a remote disconnect when
processing completions. The admin qpair will be disconnected to handle
this. The disconnect code path will manually complete queued aborts.
However, the completion callback for the abort will attempt to resubmit
other queued aborts from the queue, which will result in a very large
stack and can eventually cause a segfault.
The fix is to not resubmit queued aborts if the admin qpair is in any
kind of failed state.

Change-Id: I4a6f959232c8a1bd30c87ca50459014e556cbaa0
Signed-off-by: Vasuki Manikarnike <vasuki.manikarnike@hpe.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15114
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
Reviewed-by: Michael Haeuptle <michaelhaeuptle@gmail.com>
This commit is contained in:
Vasuki Manikarnike 2022-10-21 15:57:41 -07:00 committed by Tomasz Zawadzki
parent 71828b749f
commit 3fcee8ddcc
2 changed files with 10 additions and 0 deletions

View File

@ -4,6 +4,7 @@
*/
#include "nvme_internal.h"
#include "spdk/nvme.h"
int
spdk_nvme_ctrlr_io_cmd_raw_no_payload_build(struct spdk_nvme_ctrlr *ctrlr,
@ -546,6 +547,12 @@ nvme_ctrlr_retry_queued_abort(struct spdk_nvme_ctrlr *ctrlr)
int rc;
if (ctrlr->is_resetting || ctrlr->is_destructed || ctrlr->is_failed) {
/* Don't resubmit aborts if ctrlr is failing */
return;
}
if (spdk_nvme_ctrlr_get_admin_qp_failure_reason(ctrlr) != SPDK_NVME_QPAIR_FAILURE_NONE) {
/* Don't resubmit aborts if admin qpair is failed */
return;
}

View File

@ -51,6 +51,9 @@ DEFINE_STUB(nvme_transport_qpair_iterate_requests, int,
DEFINE_STUB(nvme_qpair_abort_queued_reqs_with_cbarg, uint32_t,
(struct spdk_nvme_qpair *qpair, void *cmd_cb_arg), 0);
DEFINE_STUB(spdk_nvme_ctrlr_get_admin_qp_failure_reason, spdk_nvme_qp_failure_reason,
(struct spdk_nvme_ctrlr *ctrlr), 0);
static int
nvme_ns_cmp(struct spdk_nvme_ns *ns1, struct spdk_nvme_ns *ns2)
{