diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 2f8ef7457..8a48b4a35 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -670,49 +670,54 @@ nvme_ctrlr_construct_intel_support_log_page_list(struct spdk_nvme_ctrlr *ctrlr, } } +struct intel_log_pages_ctx { + struct spdk_nvme_intel_log_page_directory log_page_directory; + struct spdk_nvme_ctrlr *ctrlr; +}; + +static void +nvme_ctrlr_set_intel_support_log_pages_done(void *arg, const struct spdk_nvme_cpl *cpl) +{ + struct intel_log_pages_ctx *ctx = arg; + struct spdk_nvme_ctrlr *ctrlr = ctx->ctrlr; + + if (!spdk_nvme_cpl_is_error(cpl)) { + nvme_ctrlr_construct_intel_support_log_page_list(ctrlr, &ctx->log_page_directory); + } + + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_SET_SUPPORTED_FEATURES, + ctrlr->opts.admin_timeout_ms); + free(ctx); +} + static int nvme_ctrlr_set_intel_support_log_pages(struct spdk_nvme_ctrlr *ctrlr) { int rc = 0; - struct nvme_completion_poll_status *status; - struct spdk_nvme_intel_log_page_directory *log_page_directory; + struct intel_log_pages_ctx *ctx; - log_page_directory = spdk_zmalloc(sizeof(struct spdk_nvme_intel_log_page_directory), - 64, NULL, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); - if (log_page_directory == NULL) { - NVME_CTRLR_ERRLOG(ctrlr, "could not allocate log_page_directory\n"); - return -ENXIO; - } - - status = calloc(1, sizeof(*status)); - if (!status) { - NVME_CTRLR_ERRLOG(ctrlr, "Failed to allocate status tracker\n"); - spdk_free(log_page_directory); - return -ENOMEM; - } - - rc = spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_INTEL_LOG_PAGE_DIRECTORY, - SPDK_NVME_GLOBAL_NS_TAG, log_page_directory, - sizeof(struct spdk_nvme_intel_log_page_directory), - 0, nvme_completion_poll_cb, status); - if (rc != 0) { - spdk_free(log_page_directory); - free(status); - return rc; - } - - if (nvme_wait_for_completion_timeout(ctrlr->adminq, status, - ctrlr->opts.admin_timeout_ms * 1000)) { - spdk_free(log_page_directory); - NVME_CTRLR_WARNLOG(ctrlr, "Intel log pages not supported on Intel drive!\n"); - if (!status->timed_out) { - free(status); - } + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_SET_SUPPORTED_FEATURES, + ctrlr->opts.admin_timeout_ms); return 0; } - nvme_ctrlr_construct_intel_support_log_page_list(ctrlr, log_page_directory); - spdk_free(log_page_directory); - free(status); + ctx->ctrlr = ctrlr; + + rc = spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_INTEL_LOG_PAGE_DIRECTORY, + SPDK_NVME_GLOBAL_NS_TAG, &ctx->log_page_directory, + sizeof(struct spdk_nvme_intel_log_page_directory), + 0, nvme_ctrlr_set_intel_support_log_pages_done, ctx); + if (rc != 0) { + free(ctx); + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_SET_SUPPORTED_FEATURES, + ctrlr->opts.admin_timeout_ms); + return 0; + } + + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_WAIT_FOR_SUPPORTED_INTEL_LOG_PAGES, + ctrlr->opts.admin_timeout_ms); + return 0; } @@ -886,12 +891,7 @@ nvme_ctrlr_set_supported_log_pages(struct spdk_nvme_ctrlr *ctrlr) if (ctrlr->cdata.lpa.celp) { ctrlr->log_page_supported[SPDK_NVME_LOG_COMMAND_EFFECTS_LOG] = true; } - if (ctrlr->cdata.vid == SPDK_PCI_VID_INTEL && !(ctrlr->quirks & NVME_INTEL_QUIRK_NO_LOG_PAGES)) { - rc = nvme_ctrlr_set_intel_support_log_pages(ctrlr); - if (rc != 0) { - goto out; - } - } + if (ctrlr->cdata.cmic.ana_reporting) { ctrlr->log_page_supported[SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS] = true; if (!ctrlr->opts.disable_read_ana_log_page) { @@ -903,7 +903,16 @@ nvme_ctrlr_set_supported_log_pages(struct spdk_nvme_ctrlr *ctrlr) } } -out: + if (ctrlr->cdata.vid == SPDK_PCI_VID_INTEL && !(ctrlr->quirks & NVME_INTEL_QUIRK_NO_LOG_PAGES)) { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_SET_SUPPORTED_INTEL_LOG_PAGES, + ctrlr->opts.admin_timeout_ms); + + } else { + nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_SET_SUPPORTED_FEATURES, + ctrlr->opts.admin_timeout_ms); + + } + return rc; } @@ -1393,6 +1402,10 @@ nvme_ctrlr_state_string(enum nvme_ctrlr_state state) return "wait for identify ns iocs specific"; case NVME_CTRLR_STATE_SET_SUPPORTED_LOG_PAGES: return "set supported log pages"; + case NVME_CTRLR_STATE_SET_SUPPORTED_INTEL_LOG_PAGES: + return "set supported INTEL log pages"; + case NVME_CTRLR_STATE_WAIT_FOR_SUPPORTED_INTEL_LOG_PAGES: + return "wait for supported INTEL log pages"; case NVME_CTRLR_STATE_SET_SUPPORTED_FEATURES: return "set supported features"; case NVME_CTRLR_STATE_SET_DB_BUF_CFG: @@ -3941,8 +3954,10 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr) case NVME_CTRLR_STATE_SET_SUPPORTED_LOG_PAGES: rc = nvme_ctrlr_set_supported_log_pages(ctrlr); - nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_SET_SUPPORTED_FEATURES, - ctrlr->opts.admin_timeout_ms); + break; + + case NVME_CTRLR_STATE_SET_SUPPORTED_INTEL_LOG_PAGES: + rc = nvme_ctrlr_set_intel_support_log_pages(ctrlr); break; case NVME_CTRLR_STATE_SET_SUPPORTED_FEATURES: @@ -3985,6 +4000,7 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr) case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS: case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_ID_DESCS: case NVME_CTRLR_STATE_WAIT_FOR_IDENTIFY_NS_IOCS_SPECIFIC: + case NVME_CTRLR_STATE_WAIT_FOR_SUPPORTED_INTEL_LOG_PAGES: case NVME_CTRLR_STATE_WAIT_FOR_DB_BUF_CFG: case NVME_CTRLR_STATE_WAIT_FOR_HOST_ID: spdk_nvme_qpair_process_completions(ctrlr->adminq, 0); diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index 437308842..a49ff20ee 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -749,6 +749,16 @@ enum nvme_ctrlr_state { */ NVME_CTRLR_STATE_SET_SUPPORTED_LOG_PAGES, + /** + * Set supported log pages of INTEL controller. + */ + NVME_CTRLR_STATE_SET_SUPPORTED_INTEL_LOG_PAGES, + + /** + * Waiting for supported log pages of INTEL controller. + */ + NVME_CTRLR_STATE_WAIT_FOR_SUPPORTED_INTEL_LOG_PAGES, + /** * Set supported features of the controller. */ 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 a155c9efb..bd444f872 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 @@ -371,6 +371,13 @@ spdk_nvme_ctrlr_cmd_get_log_page(struct spdk_nvme_ctrlr *ctrlr, uint8_t log_page memcpy(ptr, g_ana_descs[i], desc_size); ptr += desc_size; } + } else if (log_page == SPDK_NVME_INTEL_LOG_PAGE_DIRECTORY) { + struct spdk_nvme_intel_log_page_directory *log_page_directory = payload; + log_page_directory->read_latency_log_len = true; + log_page_directory->write_latency_log_len = true; + log_page_directory->temperature_statistics_log_len = true; + log_page_directory->smart_log_len = true; + log_page_directory->marketing_description_log_len = true; } fake_cpl_sc(cb_fn, cb_arg); @@ -2963,34 +2970,6 @@ test_nvme_ctrlr_set_supported_log_pages(void) { int rc; struct spdk_nvme_ctrlr ctrlr = {}; - struct spdk_nvme_intel_log_page_directory *log_page_directory = NULL; - - /* Intel device */ - ctrlr.cdata.lpa.celp = true; - ctrlr.cdata.vid = SPDK_PCI_VID_INTEL; - ctrlr.quirks |= NVME_INTEL_QUIRK_READ_LATENCY; - ctrlr.quirks |= NVME_INTEL_QUIRK_WRITE_LATENCY; - log_page_directory = spdk_zmalloc(sizeof(struct spdk_nvme_intel_log_page_directory), - 64, NULL, SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); - SPDK_CU_ASSERT_FATAL(log_page_directory != NULL); - - log_page_directory->temperature_statistics_log_len = 1; - log_page_directory->smart_log_len = 1; - log_page_directory->marketing_description_log_len = 1; - MOCK_SET(spdk_zmalloc, log_page_directory); - - rc = nvme_ctrlr_set_supported_log_pages(&ctrlr); - CU_ASSERT(rc == 0); - CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_LOG_ERROR] == true); - CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_LOG_HEALTH_INFORMATION] == true); - CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_LOG_FIRMWARE_SLOT] == true); - CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_LOG_COMMAND_EFFECTS_LOG] == true); - CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_LOG_READ_CMD_LATENCY] == true); - CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_LOG_WRITE_CMD_LATENCY] == true); - CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_LOG_TEMPERATURE] == true); - CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_LOG_SMART] == true); - CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_MARKETING_DESCRIPTION] == true); - MOCK_CLEAR(spdk_zmalloc); /* ana supported */ memset(&ctrlr, 0, sizeof(ctrlr)); @@ -3011,6 +2990,36 @@ test_nvme_ctrlr_set_supported_log_pages(void) free(ctrlr.copied_ana_desc); } +static void +test_nvme_ctrlr_set_intel_supported_log_pages(void) +{ + DECLARE_AND_CONSTRUCT_CTRLR(); + + SPDK_CU_ASSERT_FATAL(nvme_ctrlr_construct(&ctrlr) == 0); + + ctrlr.opts.admin_timeout_ms = NVME_TIMEOUT_INFINITE; + ctrlr.cdata.vid = SPDK_PCI_VID_INTEL; + ctrlr.state = NVME_CTRLR_STATE_SET_SUPPORTED_LOG_PAGES; + + CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0); + CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_SET_SUPPORTED_INTEL_LOG_PAGES); + + set_status_code = SPDK_NVME_SC_SUCCESS; + CU_ASSERT(nvme_ctrlr_process_init(&ctrlr) == 0); + CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_WAIT_FOR_SUPPORTED_INTEL_LOG_PAGES); + + CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_LOG_ERROR] == true); + CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_LOG_HEALTH_INFORMATION] == true); + CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_LOG_FIRMWARE_SLOT] == true); + CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_LOG_READ_CMD_LATENCY] == true); + CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_LOG_WRITE_CMD_LATENCY] == true); + CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_LOG_TEMPERATURE] == true); + CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_LOG_SMART] == true); + CU_ASSERT(ctrlr.log_page_supported[SPDK_NVME_INTEL_MARKETING_DESCRIPTION] == true); + + nvme_ctrlr_destruct(&ctrlr); +} + #define UT_ANA_DESC_SIZE (sizeof(struct spdk_nvme_ana_group_descriptor) + \ sizeof(uint32_t)) static void @@ -3238,6 +3247,7 @@ int main(int argc, char **argv) CU_ADD_TEST(suite, test_nvme_ctrlr_ns_attr_changed); CU_ADD_TEST(suite, test_nvme_ctrlr_identify_namespaces_iocs_specific_next); CU_ADD_TEST(suite, test_nvme_ctrlr_set_supported_log_pages); + CU_ADD_TEST(suite, test_nvme_ctrlr_set_intel_supported_log_pages); CU_ADD_TEST(suite, test_nvme_ctrlr_parse_ana_log_page); CU_ADD_TEST(suite, test_nvme_ctrlr_ana_resize); CU_ADD_TEST(suite, test_nvme_ctrlr_get_memory_domains);