nvme: Do not create IO qpair during ctrlr initialization

If nvme ctrlr is resetting or initializing, free_io_qids
bitmap is already freed or not created yet. In that case
an attempt to create IO qpair leads to segmentation fault.

Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Change-Id: I6a97bf81d5a568db20d23b3f88cf01e994ba42e3
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10827
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuheimatsumoto@gmail.com>
This commit is contained in:
Alexey Marchuk 2021-12-22 14:51:12 +03:00 committed by Tomasz Zawadzki
parent a2f0b6e4d3
commit 3c4a68cafc
2 changed files with 15 additions and 0 deletions

View File

@ -460,6 +460,12 @@ spdk_nvme_ctrlr_alloc_io_qpair(struct spdk_nvme_ctrlr *ctrlr,
struct spdk_nvme_io_qpair_opts opts;
int rc;
if (spdk_unlikely(ctrlr->state != NVME_CTRLR_STATE_READY)) {
/* When controller is resetting or initializing, free_io_qids is deleted or not created yet.
* We can't create IO qpair in that case */
return NULL;
}
/*
* Get the default options, then overwrite them with the user-provided options
* up to opts_size.
@ -5202,6 +5208,7 @@ spdk_nvme_ctrlr_alloc_qid(struct spdk_nvme_ctrlr *ctrlr)
{
uint32_t qid;
assert(ctrlr->free_io_qids);
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
qid = spdk_bit_array_find_first_set(ctrlr->free_io_qids, 1);
if (qid > ctrlr->opts.num_io_queues) {

View File

@ -1503,6 +1503,7 @@ setup_qpairs(struct spdk_nvme_ctrlr *ctrlr, uint32_t num_io_queues)
ctrlr->page_size = 0x1000;
ctrlr->opts.num_io_queues = num_io_queues;
ctrlr->free_io_qids = spdk_bit_array_create(num_io_queues + 1);
ctrlr->state = NVME_CTRLR_STATE_READY;
SPDK_CU_ASSERT_FATAL(ctrlr->free_io_qids != NULL);
spdk_bit_array_clear(ctrlr->free_io_qids, 0);
@ -1566,6 +1567,13 @@ test_alloc_io_qpair_rr_1(void)
/* Only 0 ~ 3 qprio is acceptable */
opts.qprio = 4;
SPDK_CU_ASSERT_FATAL(spdk_nvme_ctrlr_alloc_io_qpair(&ctrlr, &opts, sizeof(opts)) == NULL);
opts.qprio = 0;
/* IO qpair can only be created when ctrlr is in READY state */
ctrlr.state = NVME_CTRLR_STATE_ENABLE;
q0 = spdk_nvme_ctrlr_alloc_io_qpair(&ctrlr, &opts, sizeof(opts));
SPDK_CU_ASSERT_FATAL(q0 == NULL);
ctrlr.state = NVME_CTRLR_STATE_READY;
cleanup_qpairs(&ctrlr);
}