diff --git a/lib/ftl/Makefile b/lib/ftl/Makefile index d0fd29027..509fc7b4d 100644 --- a/lib/ftl/Makefile +++ b/lib/ftl/Makefile @@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk C_SRCS = ftl_band.c ftl_core.c ftl_debug.c ftl_io.c ftl_rwb.c ftl_reloc.c \ - ftl_anm.c ftl_restore.c ftl_init.c ftl_trace.c + ftl_restore.c ftl_init.c ftl_trace.c LIBNAME = ftl diff --git a/lib/ftl/ftl_anm.c b/lib/ftl/ftl_anm.c deleted file mode 100644 index 5d89ddf11..000000000 --- a/lib/ftl/ftl_anm.c +++ /dev/null @@ -1,567 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright (c) Intel Corporation. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "spdk/stdinc.h" -#include "spdk/nvme_spec.h" -#include "spdk/nvme_ocssd_spec.h" -#include "spdk/thread.h" -#include "spdk/ftl.h" -#include "ftl_anm.h" -#include "ftl_core.h" -#include "ftl_band.h" -#include "ftl_debug.h" - -/* Number of log pages read in single get_log_page call */ -#define FTL_ANM_LOG_ENTRIES 16 - -/* Structure aggregating ANM callback registered by ftl device */ -struct ftl_anm_poller { - struct spdk_ftl_dev *dev; - - ftl_anm_fn fn; - - LIST_ENTRY(ftl_anm_poller) list_entry; -}; - -struct ftl_anm_ctrlr { - /* NVMe controller */ - struct spdk_nvme_ctrlr *ctrlr; - - /* NVMe namespace */ - struct spdk_nvme_ns *ns; - - /* Outstanding ANM event counter */ - int anm_outstanding; - - /* Indicates if get log page command has been submitted to controller */ - int processing; - - /* Notification counter */ - uint64_t nc; - - /* DMA allocated buffer for log pages */ - struct spdk_ocssd_chunk_notification_entry *log; - - /* Protects ctrlr against process_admin_completions from multiple threads */ - pthread_mutex_t lock; - - /* List link */ - LIST_ENTRY(ftl_anm_ctrlr) list_entry; - - /* List of registered pollers */ - LIST_HEAD(, ftl_anm_poller) pollers; -}; - -struct ftl_anm { - struct spdk_thread *thread; - struct spdk_poller *poller; - - pthread_mutex_t lock; - /* List of registered controllers */ - LIST_HEAD(, ftl_anm_ctrlr) ctrlrs; -}; - -struct ftl_anm_init_ctx { - spdk_ftl_fn cb; - void *cb_arg; -}; - -static struct ftl_anm g_anm = { .lock = PTHREAD_MUTEX_INITIALIZER }; - -static int -ftl_anm_log_range(struct spdk_ocssd_chunk_notification_entry *log) -{ - if (log->mask.lblk) { - return FTL_ANM_RANGE_LBK; - } - - if (log->mask.chunk) { - return FTL_ANM_RANGE_CHK; - } - - if (log->mask.pu) { - return FTL_ANM_RANGE_PU; - } - - assert(0); - return FTL_ANM_RANGE_MAX; -} - -static struct ftl_anm_event * -ftl_anm_event_alloc(struct spdk_ftl_dev *dev, struct ftl_addr addr, - enum ftl_anm_range range, size_t num_lbks) -{ - struct ftl_anm_event *event; - - event = calloc(1, sizeof(*event)); - if (!event) { - return NULL; - } - - event->dev = dev; - event->addr = addr; - - switch (range) { - case FTL_ANM_RANGE_LBK: - event->num_lbks = num_lbks; - break; - case FTL_ANM_RANGE_CHK: - case FTL_ANM_RANGE_PU: - event->num_lbks = ftl_dev_lbks_in_zone(dev); - break; - default: - assert(false); - } - - - return event; -} - -static int -ftl_anm_process_log(struct ftl_anm_poller *poller, - struct spdk_ocssd_chunk_notification_entry *log) -{ - struct ftl_anm_event *event; - struct ftl_addr addr = ftl_addr_addr_unpack(poller->dev, log->lba); - struct spdk_ftl_dev *dev = poller->dev; - enum ftl_anm_range range = ftl_anm_log_range(log); - int i, num_bands = 1; - - num_bands = range != FTL_ANM_RANGE_PU ? 1 : ftl_dev_num_bands(dev); - - for (i = 0; i < num_bands; ++i) { - struct ftl_zone *zone = ftl_band_zone_from_addr(&dev->bands[i], addr); - - if (zone->state == SPDK_BDEV_ZONE_STATE_OFFLINE) { - continue; - } - - event = ftl_anm_event_alloc(dev, addr, range, log->nlb); - if (!event) { - return -ENOMEM; - } - - poller->fn(event); - addr.zone_id++; - } - - return 0; -} - -static bool -ftl_anm_in_poller_range(struct ftl_anm_poller *poller, - struct spdk_ocssd_chunk_notification_entry *log) -{ - struct spdk_ftl_dev *dev = poller->dev; - struct ftl_addr addr = ftl_addr_addr_unpack(dev, log->lba); - char buf[128]; - - if (addr.zone_id >= ftl_dev_num_bands(dev)) { - SPDK_ERRLOG("ANM log contains invalid @addr: %s\n", - ftl_addr2str(addr, buf, sizeof(buf))); - return false; - } - - return true; -} - -static int -ftl_anm_log_valid(struct ftl_anm_ctrlr *ctrlr, - struct spdk_ocssd_chunk_notification_entry *log) -{ - /* Initialize ctrlr->nc during the first log page read */ - if (!ctrlr->nc && log->nc) { - ctrlr->nc = log->nc - 1; - } - - if (log->nc > ctrlr->nc) { - ctrlr->nc = log->nc; - return 1; - } - - return 0; -} - -static void -ftl_anm_log_page_cb(void *ctx, const struct spdk_nvme_cpl *cpl) -{ - struct ftl_anm_ctrlr *ctrlr = ctx; - struct ftl_anm_poller *poller; - - pthread_mutex_lock(&ctrlr->lock); - - if (spdk_nvme_cpl_is_error(cpl)) { - SPDK_ERRLOG("Unexpected status code: [%d], status code type: [%d]\n", - cpl->status.sc, cpl->status.sct); - goto out; - } - - for (size_t i = 0; i < FTL_ANM_LOG_ENTRIES; ++i) { - if (!ftl_anm_log_valid(ctrlr, &ctrlr->log[i])) { - goto out; - } - - LIST_FOREACH(poller, &ctrlr->pollers, list_entry) { - struct spdk_ocssd_chunk_notification_entry *log = &ctrlr->log[i]; - - if (!ftl_anm_in_poller_range(poller, log)) { - continue; - } - - if (ftl_anm_process_log(poller, log)) { - SPDK_ERRLOG("Failed to process ANM log by dev: %p\n", poller->dev); - } - break; - } - } - - /* We increment anm_outstanding counter in case there are more logs in controller */ - /* than we get in single log page call */ - ctrlr->anm_outstanding++; -out: - ctrlr->processing = 0; - - pthread_mutex_unlock(&ctrlr->lock); -} - -static void -ftl_anm_aer_cb(void *ctx, const struct spdk_nvme_cpl *cpl) -{ - union spdk_nvme_async_event_completion event = { .raw = cpl->cdw0 }; - struct ftl_anm_ctrlr *ctrlr = ctx; - - if (spdk_nvme_cpl_is_error(cpl)) { - SPDK_ERRLOG("Unexpected status code: [%d], status code type: [%d]\n", - cpl->status.sc, cpl->status.sct); - return; - } - - pthread_mutex_lock(&ctrlr->lock); - - if (event.bits.async_event_type == SPDK_NVME_ASYNC_EVENT_TYPE_VENDOR && - event.bits.log_page_identifier == SPDK_OCSSD_LOG_CHUNK_NOTIFICATION) { - ctrlr->anm_outstanding++; - } - - pthread_mutex_unlock(&ctrlr->lock); -} - -static int -ftl_anm_get_log_page(struct ftl_anm_ctrlr *ctrlr) -{ - uint32_t nsid = spdk_nvme_ns_get_id(ctrlr->ns); - - ctrlr->anm_outstanding = 0; - - if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr->ctrlr, SPDK_OCSSD_LOG_CHUNK_NOTIFICATION, nsid, - ctrlr->log, sizeof(*ctrlr->log) * FTL_ANM_LOG_ENTRIES, 0, - ftl_anm_log_page_cb, (void *)ctrlr)) { - return -1; - } - - ctrlr->processing = 1; - return 0; -} - -static int -ftl_anm_poller_cb(void *ctx) -{ - struct ftl_anm *anm = ctx; - struct ftl_anm_ctrlr *ctrlr; - int rc = 0, num_processed = 0; - - pthread_mutex_lock(&anm->lock); - LIST_FOREACH(ctrlr, &anm->ctrlrs, list_entry) { - rc = spdk_nvme_ctrlr_process_admin_completions(ctrlr->ctrlr); - if (rc < 0) { - SPDK_ERRLOG("Processing admin completions failed\n"); - break; - } - - num_processed += rc; - - pthread_mutex_lock(&ctrlr->lock); - if (ctrlr->anm_outstanding && !ctrlr->processing) { - if (ftl_anm_get_log_page(ctrlr)) { - SPDK_ERRLOG("Failed to get log page from controller %p", - ctrlr->ctrlr); - } - } - pthread_mutex_unlock(&ctrlr->lock); - } - - pthread_mutex_unlock(&anm->lock); - return num_processed; -} - -static struct ftl_anm_poller * -ftl_anm_alloc_poller(struct spdk_ftl_dev *dev, ftl_anm_fn fn) -{ - struct ftl_anm_poller *poller; - - poller = calloc(1, sizeof(*poller)); - if (!poller) { - return NULL; - } - - poller->fn = fn; - poller->dev = dev; - - return poller; -} - -static void -ftl_anm_ctrlr_free(struct ftl_anm_ctrlr *ctrlr) -{ - if (!ctrlr) { - return; - } - - /* Unregister ctrlr from aer events */ - spdk_nvme_ctrlr_register_aer_callback(ctrlr->ctrlr, NULL, NULL); - - pthread_mutex_destroy(&ctrlr->lock); - spdk_dma_free(ctrlr->log); - free(ctrlr); -} - -static struct ftl_anm_ctrlr * -ftl_anm_ctrlr_alloc(struct spdk_ftl_dev *dev) -{ - struct ftl_anm_ctrlr *ctrlr; - - ctrlr = calloc(1, sizeof(*ctrlr)); - if (!ctrlr) { - return NULL; - } - - ctrlr->log = spdk_dma_zmalloc(sizeof(*ctrlr->log) * FTL_ANM_LOG_ENTRIES, - 4096, NULL); - if (!ctrlr->log) { - goto free_ctrlr; - } - - if (pthread_mutex_init(&ctrlr->lock, NULL)) { - goto free_log; - } - - /* Set the outstanding counter to force log page retrieval */ - /* to consume events already present on the controller */ - ctrlr->anm_outstanding = 1; - ctrlr->ctrlr = dev->ctrlr; - ctrlr->ns = dev->ns; - LIST_INIT(&ctrlr->pollers); - - spdk_nvme_ctrlr_register_aer_callback(ctrlr->ctrlr, ftl_anm_aer_cb, ctrlr); - return ctrlr; - -free_log: - free(ctrlr->log); -free_ctrlr: - free(ctrlr); - return NULL; -} - -static struct ftl_anm_ctrlr * -ftl_anm_find_ctrlr(struct ftl_anm *anm, struct spdk_nvme_ctrlr *ctrlr) -{ - struct ftl_anm_ctrlr *anm_ctrlr; - - LIST_FOREACH(anm_ctrlr, &anm->ctrlrs, list_entry) { - if (ctrlr == anm_ctrlr->ctrlr) { - return anm_ctrlr; - } - } - - return NULL; -} - -void -ftl_anm_event_complete(struct ftl_anm_event *event) -{ - free(event); -} - -int -ftl_anm_register_device(struct spdk_ftl_dev *dev, ftl_anm_fn fn) -{ - struct ftl_anm_poller *poller; - struct ftl_anm_ctrlr *ctrlr; - int rc = 0; - - pthread_mutex_lock(&g_anm.lock); - - ctrlr = ftl_anm_find_ctrlr(&g_anm, dev->ctrlr); - if (!ctrlr) { - ctrlr = ftl_anm_ctrlr_alloc(dev); - if (!ctrlr) { - rc = -1; - goto out; - } - - LIST_INSERT_HEAD(&g_anm.ctrlrs, ctrlr, list_entry); - } - - poller = ftl_anm_alloc_poller(dev, fn); - if (!poller) { - rc = -1; - goto out; - } - - pthread_mutex_lock(&ctrlr->lock); - LIST_INSERT_HEAD(&ctrlr->pollers, poller, list_entry); - pthread_mutex_unlock(&ctrlr->lock); -out: - pthread_mutex_unlock(&g_anm.lock); - return rc; -} - -static void -ftl_anm_unregister_device_cb(void *ctx) -{ - struct ftl_anm_init_ctx *init_ctx = ctx; - struct spdk_ftl_dev *dev = init_ctx->cb_arg; - struct ftl_anm_ctrlr *ctrlr; - struct ftl_anm_poller *poller, *temp_poller; - - pthread_mutex_lock(&g_anm.lock); - ctrlr = ftl_anm_find_ctrlr(&g_anm, dev->ctrlr); - assert(ctrlr != NULL); - pthread_mutex_lock(&ctrlr->lock); - - LIST_FOREACH_SAFE(poller, &ctrlr->pollers, list_entry, temp_poller) { - if (poller->dev == dev) { - LIST_REMOVE(poller, list_entry); - free(poller); - } - } - - pthread_mutex_unlock(&ctrlr->lock); - - /* Release the controller if there are no more pollers */ - if (LIST_EMPTY(&ctrlr->pollers)) { - if (!ctrlr->processing) { - LIST_REMOVE(ctrlr, list_entry); - ftl_anm_ctrlr_free(ctrlr); - } else { - pthread_mutex_unlock(&g_anm.lock); - spdk_thread_send_msg(g_anm.thread, ftl_anm_unregister_device_cb, ctx); - return; - } - } - - pthread_mutex_unlock(&g_anm.lock); - - init_ctx->cb(init_ctx->cb_arg, 0); - free(init_ctx); -} - -int -ftl_anm_unregister_device(struct spdk_ftl_dev *dev, spdk_ftl_fn cb) -{ - struct ftl_anm_init_ctx *ctx; - - ctx = malloc(sizeof(*ctx)); - if (!ctx) { - return -ENOMEM; - } - - ctx->cb = cb; - ctx->cb_arg = dev; - - spdk_thread_send_msg(g_anm.thread, ftl_anm_unregister_device_cb, ctx); - return 0; -} - -static void -ftl_anm_register_poller_cb(void *ctx) -{ - struct ftl_anm_init_ctx *init_ctx = ctx; - int rc = 0; - - /* TODO: adjust polling timeout */ - g_anm.poller = spdk_poller_register(ftl_anm_poller_cb, &g_anm, 1000); - if (!g_anm.poller) { - SPDK_ERRLOG("Unable to register ANM poller\n"); - rc = -ENOMEM; - } - - init_ctx->cb(init_ctx->cb_arg, rc); - free(init_ctx); -} - -int -ftl_anm_init(struct spdk_thread *thread, spdk_ftl_fn cb, void *cb_arg) -{ - struct ftl_anm_init_ctx *ctx; - - ctx = malloc(sizeof(*ctx)); - if (!ctx) { - return -ENOMEM; - } - - g_anm.thread = thread; - ctx->cb = cb; - ctx->cb_arg = cb_arg; - - spdk_thread_send_msg(thread, ftl_anm_register_poller_cb, ctx); - return 0; -} - -static void -ftl_anm_unregister_poller_cb(void *ctx) -{ - struct ftl_anm_init_ctx *init_ctx = ctx; - - spdk_poller_unregister(&g_anm.poller); - - init_ctx->cb(init_ctx->cb_arg, 0); - free(init_ctx); -} - -int -ftl_anm_free(spdk_ftl_fn cb, void *cb_arg) -{ - struct ftl_anm_init_ctx *ctx; - - ctx = malloc(sizeof(*ctx)); - if (!ctx) { - return -ENOMEM; - } - - ctx->cb = cb; - ctx->cb_arg = cb_arg; - - spdk_thread_send_msg(g_anm.thread, ftl_anm_unregister_poller_cb, ctx); - return 0; -} diff --git a/lib/ftl/ftl_anm.h b/lib/ftl/ftl_anm.h deleted file mode 100644 index 96a73dd51..000000000 --- a/lib/ftl/ftl_anm.h +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright (c) Intel Corporation. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FTL_ANM_H -#define FTL_ANM_H - -#include "spdk/thread.h" -#include "ftl_addr.h" - -struct ftl_nvme_ctrlr; -struct ftl_anm_event; -struct spdk_ftl_dev; - -typedef void (*ftl_anm_fn)(struct ftl_anm_event *event); - -enum ftl_anm_range { - FTL_ANM_RANGE_LBK, - FTL_ANM_RANGE_CHK, - FTL_ANM_RANGE_PU, - FTL_ANM_RANGE_MAX, -}; - -struct ftl_anm_event { - /* Owner device */ - struct spdk_ftl_dev *dev; - - /* First block address */ - struct ftl_addr addr; - - /* Number of logical blocks */ - size_t num_lbks; -}; - -int ftl_anm_init(struct spdk_thread *thread, spdk_ftl_fn cb, void *cb_arg); -int ftl_anm_free(spdk_ftl_fn cb, void *cb_arg); -int ftl_anm_register_device(struct spdk_ftl_dev *dev, ftl_anm_fn fn); -int ftl_anm_unregister_device(struct spdk_ftl_dev *dev, spdk_ftl_fn cb); -void ftl_anm_event_complete(struct ftl_anm_event *event); - -#endif /* FTL_ANM_H */ diff --git a/lib/ftl/ftl_core.c b/lib/ftl/ftl_core.c index 9ad514ec8..b7823d2e3 100644 --- a/lib/ftl/ftl_core.c +++ b/lib/ftl/ftl_core.c @@ -44,7 +44,6 @@ #include "ftl_core.h" #include "ftl_band.h" #include "ftl_io.h" -#include "ftl_anm.h" #include "ftl_rwb.h" #include "ftl_debug.h" #include "ftl_reloc.h" @@ -2116,37 +2115,6 @@ spdk_ftl_flush(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg) return ftl_flush_rwb(dev, cb_fn, cb_arg); } -static void -_ftl_process_anm_event(void *ctx) -{ - ftl_process_anm_event((struct ftl_anm_event *)ctx); -} - -void -ftl_process_anm_event(struct ftl_anm_event *event) -{ - struct spdk_ftl_dev *dev = event->dev; - struct ftl_band *band; - size_t lbkoff; - - /* Drop any ANM requests until the device is initialized */ - if (!dev->initialized) { - ftl_anm_event_complete(event); - return; - } - - if (!ftl_check_core_thread(dev)) { - spdk_thread_send_msg(ftl_get_core_thread(dev), _ftl_process_anm_event, event); - return; - } - - band = ftl_band_from_addr(dev, event->addr); - lbkoff = ftl_band_lbkoff_from_addr(band, event->addr); - - ftl_reloc_add(dev->reloc, band, lbkoff, event->num_lbks, 0, false); - ftl_anm_event_complete(event); -} - bool ftl_addr_is_written(struct ftl_band *band, struct ftl_addr addr) { diff --git a/lib/ftl/ftl_init.c b/lib/ftl/ftl_init.c index a05354f17..2bff6bc99 100644 --- a/lib/ftl/ftl_init.c +++ b/lib/ftl/ftl_init.c @@ -43,7 +43,6 @@ #include "spdk/bdev_zone.h" #include "ftl_core.h" -#include "ftl_anm.h" #include "ftl_io.h" #include "ftl_reloc.h" #include "ftl_rwb.h" @@ -662,10 +661,6 @@ _ftl_dev_init_thread(void *ctx) assert(0); } - if (spdk_get_thread() == ftl_get_core_thread(dev)) { - ftl_anm_register_device(dev, ftl_process_anm_event); - } - thread->ioch = spdk_get_io_channel(dev); } @@ -1233,39 +1228,19 @@ ftl_nv_cache_header_fini_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb spdk_thread_send_msg(dev->fini_ctx.thread, ftl_halt_complete_cb, dev); } -static void -_ftl_anm_unregister_cb(void *ctx) -{ - struct spdk_ftl_dev *dev = ctx; - - if (ftl_dev_has_nv_cache(dev)) { - ftl_nv_cache_write_header(&dev->nv_cache, true, ftl_nv_cache_header_fini_cb, dev); - } else { - dev->halt_complete_status = 0; - spdk_thread_send_msg(dev->fini_ctx.thread, ftl_halt_complete_cb, dev); - } -} - -static void -ftl_anm_unregister_cb(void *ctx, int status) -{ - struct spdk_ftl_dev *dev = ctx; - - spdk_thread_send_msg(ftl_get_core_thread(dev), _ftl_anm_unregister_cb, dev); -} - static int ftl_halt_poller(void *ctx) { struct spdk_ftl_dev *dev = ctx; - int rc; if (!dev->core_thread.poller && !dev->read_thread.poller) { - rc = ftl_anm_unregister_device(dev, ftl_anm_unregister_cb); - if (spdk_unlikely(rc != 0)) { - SPDK_ERRLOG("Failed to unregister ANM device, will retry later\n"); + spdk_poller_unregister(&dev->fini_ctx.poller); + + if (ftl_dev_has_nv_cache(dev)) { + ftl_nv_cache_write_header(&dev->nv_cache, true, ftl_nv_cache_header_fini_cb, dev); } else { - spdk_poller_unregister(&dev->fini_ctx.poller); + dev->halt_complete_status = 0; + spdk_thread_send_msg(dev->fini_ctx.thread, ftl_halt_complete_cb, dev); } } @@ -1311,13 +1286,15 @@ spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_init_fn cb_fn, void *cb_arg int spdk_ftl_module_init(const struct ftl_module_init_opts *opts, spdk_ftl_fn cb, void *cb_arg) { - return ftl_anm_init(opts->anm_thread, cb, cb_arg); + cb(cb_arg, 0); + return 0; } int spdk_ftl_module_fini(spdk_ftl_fn cb, void *cb_arg) { - return ftl_anm_free(cb, cb_arg); + cb(cb_arg, 0); + return 0; } SPDK_LOG_REGISTER_COMPONENT("ftl_init", SPDK_LOG_FTL_INIT)