From 81e3797452ea5138a9288c3187b363842e4dcb8e Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Tue, 11 Jun 2019 12:17:17 +0200 Subject: [PATCH] lib/ftl: distinct non-volatile cache recovery phase Change-Id: I6936905d4a031508a85729e61ac72a352a490e14 Signed-off-by: Konrad Sztyber Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/458104 Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Mateusz Kozlowski Reviewed-by: Darek Stojaczyk --- lib/ftl/ftl_core.h | 1 + lib/ftl/ftl_init.c | 28 ++++++++++++++++++++++------ lib/ftl/ftl_restore.c | 21 ++++++++++++--------- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/ftl/ftl_core.h b/lib/ftl/ftl_core.h index e7f7d9507..d9fb13288 100644 --- a/lib/ftl/ftl_core.h +++ b/lib/ftl/ftl_core.h @@ -280,6 +280,7 @@ size_t ftl_lba_map_num_lbks(const struct spdk_ftl_dev *dev); size_t ftl_head_md_num_lbks(const struct spdk_ftl_dev *dev); int ftl_restore_md(struct spdk_ftl_dev *dev, ftl_restore_fn cb); int ftl_restore_device(struct ftl_restore *restore, ftl_restore_fn cb); +void ftl_restore_nv_cache(struct ftl_restore *restore, ftl_restore_fn cb); int ftl_band_set_direct_access(struct ftl_band *band, bool access); int ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_ppa ppa, struct spdk_ocssd_chunk_information_entry *info, diff --git a/lib/ftl/ftl_init.c b/lib/ftl/ftl_init.c index 97f56dc27..04eda9c0f 100644 --- a/lib/ftl/ftl_init.c +++ b/lib/ftl/ftl_init.c @@ -974,23 +974,39 @@ ftl_setup_initial_state(struct spdk_ftl_dev *dev) return 0; } +static void +ftl_restore_nv_cache_cb(struct spdk_ftl_dev *dev, struct ftl_restore *restore, int status) +{ + if (spdk_unlikely(status != 0)) { + SPDK_ERRLOG("Failed to restore the non-volatile cache state\n"); + ftl_init_fail(dev); + return; + } + + ftl_init_complete(dev); +} + static void ftl_restore_device_cb(struct spdk_ftl_dev *dev, struct ftl_restore *restore, int status) { if (status) { SPDK_ERRLOG("Failed to restore the device from the SSD\n"); - goto error; + ftl_init_fail(dev); + return; } if (ftl_init_bands_state(dev)) { SPDK_ERRLOG("Unable to finish the initialization\n"); - goto error; + ftl_init_fail(dev); + return; } - ftl_init_complete(dev); - return; -error: - ftl_init_fail(dev); + if (!dev->nv_cache.bdev_desc) { + ftl_init_complete(dev); + return; + } + + ftl_restore_nv_cache(restore, ftl_restore_nv_cache_cb); } static void diff --git a/lib/ftl/ftl_restore.c b/lib/ftl/ftl_restore.c index 2d9d7eece..821cb6edd 100644 --- a/lib/ftl/ftl_restore.c +++ b/lib/ftl/ftl_restore.c @@ -118,7 +118,7 @@ struct ftl_restore { /* LBA map buffer */ void *lba_map; /* Indicates we're in the final phase of the restoration */ - bool l2p_phase; + bool final_phase; /* Non-volatile cache recovery */ struct ftl_nv_cache_restore nv_cache; }; @@ -163,7 +163,7 @@ ftl_restore_init(struct spdk_ftl_dev *dev, ftl_restore_fn cb) restore->dev = dev; restore->cb = cb; - restore->l2p_phase = false; + restore->final_phase = false; restore->bands = calloc(ftl_dev_num_bands(dev), sizeof(*restore->bands)); if (!restore->bands) { @@ -203,10 +203,10 @@ static void ftl_restore_complete(struct ftl_restore *restore, int status) { struct ftl_restore *ctx = status ? NULL : restore; - bool l2p_phase = restore->l2p_phase; + bool final_phase = restore->final_phase; restore->cb(restore->dev, ctx, status); - if (status || l2p_phase) { + if (status || final_phase) { ftl_restore_free(restore); } } @@ -630,8 +630,8 @@ out: spdk_bdev_free_io(bdev_io); } -static void -ftl_restore_nv_cache(struct ftl_restore *restore) +void +ftl_restore_nv_cache(struct ftl_restore *restore, ftl_restore_fn cb) { struct spdk_ftl_dev *dev = restore->dev; struct spdk_bdev *bdev; @@ -645,9 +645,13 @@ ftl_restore_nv_cache(struct ftl_restore *restore) ioch = spdk_io_channel_get_ctx(dev->ioch); bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc); alignment = spdk_max(spdk_bdev_get_buf_align(bdev), sizeof(uint64_t)); + nvc_restore->nv_cache = nv_cache; nvc_restore->ioch = ioch->cache_ioch; + restore->final_phase = true; + restore->cb = cb; + for (i = 0; i < FTL_NV_CACHE_RESTORE_DEPTH; ++i) { block = &nvc_restore->block[i]; block->parent = nvc_restore; @@ -912,8 +916,6 @@ ftl_restore_tail_md_cb(struct ftl_io *io, void *ctx, int status) if (!STAILQ_EMPTY(&restore->pad_bands)) { spdk_thread_send_msg(ftl_get_core_thread(dev), ftl_restore_pad_open_bands, restore); - } else if (dev->nv_cache.bdev_desc) { - ftl_restore_nv_cache(restore); } else { ftl_restore_complete(restore, 0); } @@ -945,11 +947,12 @@ ftl_restore_tail_md(struct ftl_restore_band *rband) int ftl_restore_device(struct ftl_restore *restore, ftl_restore_fn cb) { + struct spdk_ftl_dev *dev = restore->dev; struct ftl_restore_band *rband; - restore->l2p_phase = true; restore->current = 0; restore->cb = cb; + restore->final_phase = dev->nv_cache.bdev_desc == NULL; /* If restore_device is called, there must be at least one valid band */ rband = ftl_restore_next_band(restore);