1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "ftl_core.h" 7 #include "ftl_utils.h" 8 #include "ftl_mngt.h" 9 #include "ftl_mngt_steps.h" 10 #include "ftl_internal.h" 11 #include "ftl_nv_cache.h" 12 #include "ftl_debug.h" 13 14 void 15 ftl_mngt_check_conf(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 16 { 17 if (ftl_conf_is_valid(&dev->conf)) { 18 ftl_mngt_next_step(mngt); 19 } else { 20 ftl_mngt_fail_step(mngt); 21 } 22 } 23 24 void 25 ftl_mngt_init_nv_cache(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 26 { 27 if (ftl_nv_cache_init(dev)) { 28 FTL_ERRLOG(dev, "Unable to initialize persistent cache\n"); 29 ftl_mngt_fail_step(mngt); 30 return; 31 } 32 33 ftl_mngt_next_step(mngt); 34 } 35 36 void 37 ftl_mngt_deinit_nv_cache(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 38 { 39 ftl_nv_cache_deinit(dev); 40 ftl_mngt_next_step(mngt); 41 } 42 43 static void 44 user_clear_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status) 45 { 46 struct ftl_mngt_process *mngt = md->owner.cb_ctx; 47 48 if (status) { 49 FTL_ERRLOG(ftl_mngt_get_dev(mngt), "FTL NV Cache: ERROR of clearing user cache data\n"); 50 ftl_mngt_fail_step(mngt); 51 } else { 52 ftl_mngt_next_step(mngt); 53 } 54 } 55 56 void 57 ftl_mngt_scrub_nv_cache(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 58 { 59 struct ftl_layout_region *region = &dev->layout.region[FTL_LAYOUT_REGION_TYPE_DATA_NVC]; 60 struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_DATA_NVC]; 61 union ftl_md_vss vss; 62 63 FTL_NOTICELOG(dev, "First startup needs to scrub nv cache data region, this may take some time.\n"); 64 FTL_NOTICELOG(dev, "Scrubbing %lluGiB\n", region->current.blocks * FTL_BLOCK_SIZE / GiB); 65 66 /* Need to scrub user data, so in case of dirty shutdown the recovery won't 67 * pull in data during open chunks recovery from any previous instance 68 */ 69 md->cb = user_clear_cb; 70 md->owner.cb_ctx = mngt; 71 72 vss.version.md_version = region->current.version; 73 vss.nv_cache.lba = FTL_ADDR_INVALID; 74 ftl_md_clear(md, 0, &vss); 75 } 76 77 void 78 ftl_mngt_finalize_startup(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 79 { 80 dev->initialized = 1; 81 82 ftl_nv_cache_resume(&dev->nv_cache); 83 84 ftl_mngt_next_step(mngt); 85 } 86 87 void 88 ftl_mngt_start_core_poller(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 89 { 90 dev->core_poller = SPDK_POLLER_REGISTER(ftl_core_poller, dev, 0); 91 if (!dev->core_poller) { 92 FTL_ERRLOG(dev, "Unable to register core poller\n"); 93 ftl_mngt_fail_step(mngt); 94 return; 95 } 96 97 ftl_mngt_next_step(mngt); 98 } 99 100 void 101 ftl_mngt_stop_core_poller(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 102 { 103 dev->halt = true; 104 105 if (dev->core_poller) { 106 ftl_mngt_continue_step(mngt); 107 } else { 108 ftl_mngt_next_step(mngt); 109 } 110 } 111 112 void 113 ftl_mngt_dump_stats(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt) 114 { 115 ftl_dev_dump_stats(dev); 116 ftl_mngt_next_step(mngt); 117 } 118