From 2adfab84285a1cc3863d8bcf8855da938b077e48 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Tue, 21 Dec 2021 23:18:29 +0000 Subject: [PATCH] nvme: restart discovery log when genctr changes Each portion of the discovery log has a header which includes a 'genctr'. This number indicates the current generation of the discovery log. If this number changes during the process of fetching the discovery log in multiple chunks, wait for the current fetch to complete, but then start over. Signed-off-by: Jim Harris Change-Id: I5f8623593b7f935eecc37a98daf92e7d8c0dd566 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10813 Tested-by: SPDK CI Jenkins Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Reviewed-by: Shuhei Matsumoto Reviewed-by: Changpeng Liu --- lib/nvme/nvme_discovery.c | 47 ++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/lib/nvme/nvme_discovery.c b/lib/nvme/nvme_discovery.c index 54896544a..247d9290c 100644 --- a/lib/nvme/nvme_discovery.c +++ b/lib/nvme/nvme_discovery.c @@ -44,11 +44,37 @@ struct nvme_discovery_ctx { uint32_t outstanding_commands; }; +static void +get_log_page_completion_final(void *cb_arg, const struct spdk_nvme_cpl *cpl) +{ + struct nvme_discovery_ctx *ctx = cb_arg; + int rc; + + if (spdk_nvme_cpl_is_error(cpl)) { + free(ctx->log_page); + ctx->cb_fn(ctx->cb_arg, 0, cpl, NULL); + free(ctx); + return; + } + + /* Compare original genctr with latest genctr. If it changed, we need to restart. */ + if (ctx->log_page->genctr == ctx->genctr) { + ctx->cb_fn(ctx->cb_arg, 0, cpl, ctx->log_page); + } else { + free(ctx->log_page); + rc = spdk_nvme_ctrlr_get_discovery_log_page(ctx->ctrlr, ctx->cb_fn, ctx->cb_arg); + if (rc != 0) { + ctx->cb_fn(ctx->cb_arg, rc, NULL, NULL); + } + } + free(ctx); +} + static void get_log_page_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl) { struct nvme_discovery_ctx *ctx = cb_arg; - struct spdk_nvmf_discovery_log_page *log_page; + int rc; if (spdk_nvme_cpl_is_error(cpl)) { /* Only save the cpl for the first error that we encounter. */ @@ -61,16 +87,21 @@ get_log_page_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl) return; } - if (!spdk_nvme_cpl_is_error(&ctx->cpl)) { - log_page = ctx->log_page; - } else { - /* We had an error, so don't return the log page to the caller. */ - log_page = NULL; + if (spdk_nvme_cpl_is_error(&ctx->cpl)) { free(ctx->log_page); + ctx->cb_fn(ctx->cb_arg, 0, &ctx->cpl, NULL); + free(ctx); + return; } - ctx->cb_fn(ctx->cb_arg, 0, &ctx->cpl, log_page); - free(ctx); + rc = spdk_nvme_ctrlr_cmd_get_log_page(ctx->ctrlr, SPDK_NVME_LOG_DISCOVERY, 0, + &ctx->genctr, sizeof(ctx->genctr), 0, + get_log_page_completion_final, ctx); + if (rc != 0) { + free(ctx->log_page); + ctx->cb_fn(ctx->cb_arg, rc, NULL, NULL); + free(ctx); + } } static void