diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index d8c13beaf..264d0c47e 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -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) { diff --git a/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c b/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c index 57a80174e..b7362c63a 100644 --- a/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c +++ b/test/unit/lib/nvme/nvme_ctrlr.c/nvme_ctrlr_ut.c @@ -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); }