diff --git a/lib/nvme/nvme.c b/lib/nvme/nvme.c index 7b313addb..abd2e3cc2 100644 --- a/lib/nvme/nvme.c +++ b/lib/nvme/nvme.c @@ -142,6 +142,33 @@ spdk_nvme_wait_for_completion(struct spdk_nvme_qpair *qpair, return spdk_nvme_wait_for_completion_robust_lock(qpair, status, NULL); } +int +spdk_nvme_wait_for_completion_timeout(struct spdk_nvme_qpair *qpair, + struct nvme_completion_poll_status *status, + uint64_t timeout_in_secs) +{ + uint64_t timeout_tsc = 0; + + memset(&status->cpl, 0, sizeof(status->cpl)); + status->done = false; + if (timeout_in_secs) { + timeout_tsc = spdk_get_ticks() + timeout_in_secs * spdk_get_ticks_hz(); + } + + while (status->done == false) { + spdk_nvme_qpair_process_completions(qpair, 0); + if (timeout_tsc && spdk_get_ticks() > timeout_tsc) { + break; + } + } + + if (status->done == false) { + return -EIO; + } + + return spdk_nvme_cpl_is_error(&status->cpl) ? -EIO : 0; +} + static void nvme_user_copy_cmd_complete(void *arg, const struct spdk_nvme_cpl *cpl) { diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 280fe1e66..2982b6c5a 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -410,7 +410,8 @@ static int nvme_ctrlr_set_intel_support_log_pages(struct spdk_nvme_ctrlr *ctrlr) return rc; } - if (spdk_nvme_wait_for_completion(ctrlr->adminq, &status)) { + if (spdk_nvme_wait_for_completion_timeout(ctrlr->adminq, &status, + ctrlr->opts.admin_timeout_ms / 1000)) { spdk_free(log_page_directory); SPDK_WARNLOG("Intel log pages not supported on Intel drive!\n"); return 0; diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index f9e458fed..923a520bd 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -793,6 +793,9 @@ int spdk_nvme_wait_for_completion(struct spdk_nvme_qpair *qpair, int spdk_nvme_wait_for_completion_robust_lock(struct spdk_nvme_qpair *qpair, struct nvme_completion_poll_status *status, pthread_mutex_t *robust_mutex); +int spdk_nvme_wait_for_completion_timeout(struct spdk_nvme_qpair *qpair, + struct nvme_completion_poll_status *status, + uint64_t timeout_in_secs); struct spdk_nvme_ctrlr_process *spdk_nvme_ctrlr_get_process(struct spdk_nvme_ctrlr *ctrlr, pid_t pid); 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 468e15b7e..156789644 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 @@ -293,6 +293,13 @@ spdk_nvme_wait_for_completion(struct spdk_nvme_qpair *qpair, return spdk_nvme_wait_for_completion_robust_lock(qpair, status, NULL); } +int +spdk_nvme_wait_for_completion_timeout(struct spdk_nvme_qpair *qpair, + struct nvme_completion_poll_status *status, + uint64_t timeout_in_secs) +{ + return spdk_nvme_wait_for_completion_robust_lock(qpair, status, NULL); +} int nvme_ctrlr_cmd_set_async_event_config(struct spdk_nvme_ctrlr *ctrlr,