LCOV - code coverage report
Current view: top level - lib/ftl/mngt - ftl_mngt_misc.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 0 230 0.0 %
Date: 2024-07-15 18:22:12 Functions: 0 30 0.0 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2022 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_band.h"
      11             : #include "ftl_internal.h"
      12             : #include "ftl_nv_cache.h"
      13             : #include "ftl_debug.h"
      14             : #include "ftl_utils.h"
      15             : 
      16             : void
      17           0 : ftl_mngt_check_conf(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
      18             : {
      19           0 :         if (ftl_conf_is_valid(&dev->conf)) {
      20           0 :                 ftl_mngt_next_step(mngt);
      21             :         } else {
      22           0 :                 ftl_mngt_fail_step(mngt);
      23             :         }
      24           0 : }
      25             : 
      26             : static int
      27           0 : init_p2l_map_pool(struct spdk_ftl_dev *dev)
      28             : {
      29           0 :         size_t p2l_pool_el_blks = spdk_divide_round_up(ftl_p2l_map_pool_elem_size(dev), FTL_BLOCK_SIZE);
      30           0 :         size_t p2l_pool_buf_blks = P2L_MEMPOOL_SIZE * p2l_pool_el_blks;
      31             :         void *p2l_pool_buf;
      32             : 
      33           0 :         dev->p2l_pool_md = ftl_md_create(dev, p2l_pool_buf_blks, 0, "p2l_pool",
      34             :                                          ftl_md_create_shm_flags(dev), NULL);
      35           0 :         if (!dev->p2l_pool_md) {
      36           0 :                 return -ENOMEM;
      37             :         }
      38             : 
      39           0 :         p2l_pool_buf = ftl_md_get_buffer(dev->p2l_pool_md);
      40           0 :         dev->p2l_pool = ftl_mempool_create_ext(p2l_pool_buf, P2L_MEMPOOL_SIZE,
      41           0 :                                                p2l_pool_el_blks * FTL_BLOCK_SIZE,
      42             :                                                FTL_BLOCK_SIZE);
      43           0 :         if (!dev->p2l_pool) {
      44           0 :                 return -ENOMEM;
      45             :         }
      46             : 
      47           0 :         if (!ftl_fast_startup(dev)) {
      48           0 :                 ftl_mempool_initialize_ext(dev->p2l_pool);
      49             :         }
      50             : 
      51           0 :         return 0;
      52             : }
      53             : 
      54             : static int
      55           0 : init_band_md_pool(struct spdk_ftl_dev *dev)
      56             : {
      57           0 :         dev->band_md_pool = ftl_mempool_create(P2L_MEMPOOL_SIZE,
      58             :                                                sizeof(struct ftl_band_md),
      59             :                                                FTL_BLOCK_SIZE,
      60             :                                                SPDK_ENV_SOCKET_ID_ANY);
      61           0 :         if (!dev->band_md_pool) {
      62           0 :                 return -ENOMEM;
      63             :         }
      64             : 
      65           0 :         return 0;
      66             : }
      67             : 
      68             : void
      69           0 : ftl_mngt_init_mem_pools(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
      70             : {
      71           0 :         if (init_p2l_map_pool(dev)) {
      72           0 :                 ftl_mngt_fail_step(mngt);
      73           0 :                 return;
      74             :         }
      75             : 
      76           0 :         if (init_band_md_pool(dev)) {
      77           0 :                 ftl_mngt_fail_step(mngt);
      78           0 :                 return;
      79             :         }
      80             : 
      81           0 :         ftl_mngt_next_step(mngt);
      82             : }
      83             : 
      84             : void
      85           0 : ftl_mngt_deinit_mem_pools(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
      86             : {
      87           0 :         if (dev->p2l_pool) {
      88           0 :                 ftl_mempool_destroy_ext(dev->p2l_pool);
      89           0 :                 dev->p2l_pool = NULL;
      90             :         }
      91             : 
      92           0 :         if (dev->p2l_pool_md) {
      93           0 :                 ftl_md_destroy(dev->p2l_pool_md, ftl_md_destroy_shm_flags(dev));
      94           0 :                 dev->p2l_pool_md = NULL;
      95             :         }
      96             : 
      97           0 :         if (dev->band_md_pool) {
      98           0 :                 ftl_mempool_destroy(dev->band_md_pool);
      99           0 :                 dev->band_md_pool = NULL;
     100             :         }
     101             : 
     102           0 :         ftl_mngt_next_step(mngt);
     103           0 : }
     104             : 
     105             : void
     106           0 : ftl_mngt_init_reloc(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     107             : {
     108           0 :         dev->reloc = ftl_reloc_init(dev);
     109           0 :         if (!dev->reloc) {
     110           0 :                 FTL_ERRLOG(dev, "Unable to initialize reloc structures\n");
     111           0 :                 ftl_mngt_fail_step(mngt);
     112           0 :                 return;
     113             :         }
     114             : 
     115           0 :         ftl_mngt_next_step(mngt);
     116             : }
     117             : 
     118             : void
     119           0 : ftl_mngt_deinit_reloc(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     120             : {
     121           0 :         ftl_reloc_free(dev->reloc);
     122           0 :         ftl_mngt_next_step(mngt);
     123           0 : }
     124             : 
     125             : void
     126           0 : ftl_mngt_init_nv_cache(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     127             : {
     128           0 :         if (ftl_nv_cache_init(dev)) {
     129           0 :                 FTL_ERRLOG(dev, "Unable to initialize persistent cache\n");
     130           0 :                 ftl_mngt_fail_step(mngt);
     131           0 :                 return;
     132             :         }
     133             : 
     134           0 :         ftl_mngt_next_step(mngt);
     135             : }
     136             : 
     137             : void
     138           0 : ftl_mngt_deinit_nv_cache(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     139             : {
     140           0 :         ftl_nv_cache_deinit(dev);
     141           0 :         ftl_mngt_next_step(mngt);
     142           0 : }
     143             : 
     144             : static void
     145           0 : user_clear_cb(struct spdk_ftl_dev *dev, void *cb_ctx, int status)
     146             : {
     147           0 :         struct ftl_mngt_process *mngt = cb_ctx;
     148             : 
     149           0 :         if (status) {
     150           0 :                 FTL_ERRLOG(ftl_mngt_get_dev(mngt), "FTL NV Cache: ERROR of clearing user cache data\n");
     151           0 :                 ftl_mngt_fail_step(mngt);
     152             :         } else {
     153           0 :                 ftl_mngt_next_step(mngt);
     154             :         }
     155           0 : }
     156             : 
     157             : void
     158           0 : ftl_mngt_scrub_nv_cache(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     159             : {
     160           0 :         bool is_first_start = (dev->conf.mode & SPDK_FTL_MODE_CREATE) != 0;
     161           0 :         bool is_major_upgrade = dev->sb->clean == 1 && dev->sb_shm->shm_clean == 0 &&
     162           0 :                                 dev->sb->upgrade_ready == 1;
     163             : 
     164           0 :         if (is_first_start || is_major_upgrade) {
     165           0 :                 FTL_NOTICELOG(dev, "NV cache data region needs scrubbing, this may take a while.\n");
     166           0 :                 FTL_NOTICELOG(dev, "Scrubbing %"PRIu64" chunks\n", dev->layout.nvc.chunk_count);
     167             : 
     168             :                 /* Need to scrub user data, so in case of dirty shutdown the recovery won't
     169             :                  * pull in data during open chunks recovery from any previous instance (since during short
     170             :                  * tests it's very likely that chunks seq_id will be in line between new head md and old VSS)
     171             :                  */
     172           0 :                 ftl_nv_cache_scrub(dev, user_clear_cb, mngt);
     173             :         } else {
     174           0 :                 ftl_mngt_skip_step(mngt);
     175             :         }
     176           0 : }
     177             : 
     178             : void
     179           0 : ftl_mngt_finalize_startup(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     180             : {
     181           0 :         if (ftl_bitmap_find_first_set(dev->trim_map, 0, UINT64_MAX) != UINT64_MAX) {
     182           0 :                 dev->trim_in_progress = true;
     183             :         }
     184             : 
     185           0 :         ftl_property_register(dev, "superblock_version", &dev->sb->header.version,
     186             :                               sizeof(dev->sb->header.version), NULL, NULL,
     187             :                               ftl_property_dump_uint64, NULL, NULL, false);
     188             : 
     189             :         /* Clear the limit applications as they're incremented incorrectly by
     190             :          * the initialization code.
     191             :          */
     192           0 :         memset(dev->stats.limits, 0, sizeof(dev->stats.limits));
     193           0 :         dev->initialized = 1;
     194           0 :         dev->sb_shm->shm_ready = true;
     195             : 
     196           0 :         ftl_l2p_resume(dev);
     197           0 :         ftl_reloc_resume(dev->reloc);
     198           0 :         ftl_writer_resume(&dev->writer_user);
     199           0 :         ftl_writer_resume(&dev->writer_gc);
     200           0 :         ftl_nv_cache_resume(&dev->nv_cache);
     201             : 
     202           0 :         ftl_mngt_next_step(mngt);
     203           0 : }
     204             : 
     205             : void
     206           0 : ftl_mngt_start_core_poller(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     207             : {
     208           0 :         dev->core_poller = SPDK_POLLER_REGISTER(ftl_core_poller, dev, 0);
     209           0 :         if (!dev->core_poller) {
     210           0 :                 FTL_ERRLOG(dev, "Unable to register core poller\n");
     211           0 :                 ftl_mngt_fail_step(mngt);
     212           0 :                 return;
     213             :         }
     214             : 
     215           0 :         ftl_mngt_next_step(mngt);
     216             : }
     217             : 
     218             : void
     219           0 : ftl_mngt_stop_core_poller(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     220             : {
     221           0 :         dev->halt = true;
     222             : 
     223           0 :         if (dev->core_poller) {
     224           0 :                 ftl_mngt_continue_step(mngt);
     225             :         } else {
     226           0 :                 ftl_mngt_next_step(mngt);
     227             :         }
     228           0 : }
     229             : 
     230             : void
     231           0 : ftl_mngt_dump_stats(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     232             : {
     233           0 :         ftl_dev_dump_bands(dev);
     234           0 :         ftl_dev_dump_stats(dev);
     235           0 :         ftl_mngt_next_step(mngt);
     236           0 : }
     237             : 
     238             : void
     239           0 : ftl_mngt_init_vld_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     240             : {
     241           0 :         struct ftl_md *valid_map_md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_VALID_MAP];
     242             : 
     243           0 :         dev->valid_map = ftl_bitmap_create(ftl_md_get_buffer(valid_map_md),
     244             :                                            ftl_md_get_buffer_size(valid_map_md));
     245           0 :         if (!dev->valid_map) {
     246           0 :                 FTL_ERRLOG(dev, "Failed to create valid map\n");
     247           0 :                 ftl_mngt_fail_step(mngt);
     248           0 :                 return;
     249             :         }
     250             : 
     251           0 :         ftl_mngt_next_step(mngt);
     252             : }
     253             : 
     254             : void
     255           0 : ftl_mngt_deinit_vld_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     256             : {
     257           0 :         if (dev->valid_map) {
     258           0 :                 ftl_bitmap_destroy(dev->valid_map);
     259           0 :                 dev->valid_map = NULL;
     260             :         }
     261             : 
     262           0 :         ftl_mngt_next_step(mngt);
     263           0 : }
     264             : void
     265           0 : ftl_mngt_init_trim_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     266             : {
     267           0 :         uint64_t num_l2p_pages = spdk_divide_round_up(dev->num_lbas, dev->layout.l2p.lbas_in_page);
     268           0 :         uint64_t map_blocks = ftl_bitmap_bits_to_blocks(num_l2p_pages);
     269             : 
     270           0 :         dev->trim_map_md = ftl_md_create(dev,
     271             :                                          map_blocks,
     272             :                                          0,
     273             :                                          "trim_bitmap",
     274             :                                          ftl_md_create_shm_flags(dev), NULL);
     275             : 
     276           0 :         if (!dev->trim_map_md) {
     277           0 :                 FTL_ERRLOG(dev, "Failed to create trim bitmap md\n");
     278           0 :                 ftl_mngt_fail_step(mngt);
     279           0 :                 return;
     280             :         }
     281             : 
     282           0 :         dev->trim_map = ftl_bitmap_create(ftl_md_get_buffer(dev->trim_map_md),
     283             :                                           ftl_md_get_buffer_size(dev->trim_map_md));
     284             : 
     285           0 :         if (!dev->trim_map) {
     286           0 :                 FTL_ERRLOG(dev, "Failed to create trim map\n");
     287           0 :                 ftl_mngt_fail_step(mngt);
     288           0 :                 return;
     289             :         }
     290             : 
     291           0 :         ftl_mngt_next_step(mngt);
     292             : }
     293             : 
     294             : static void
     295           0 : trim_clear_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
     296             : {
     297           0 :         struct ftl_mngt_process *mngt = md->owner.cb_ctx;
     298             : 
     299           0 :         if (status) {
     300           0 :                 ftl_mngt_fail_step(mngt);
     301             :         } else {
     302           0 :                 ftl_mngt_next_step(mngt);
     303             :         }
     304           0 : }
     305             : 
     306             : void
     307           0 : ftl_mngt_trim_metadata_clear(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     308             : {
     309           0 :         struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_TRIM_MD];
     310             : 
     311           0 :         md->cb = trim_clear_cb;
     312           0 :         md->owner.cb_ctx = mngt;
     313           0 :         ftl_md_clear(md, 0, NULL);
     314           0 : }
     315             : 
     316             : void
     317           0 : ftl_mngt_trim_log_clear(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     318             : {
     319           0 :         struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_TRIM_LOG];
     320             : 
     321           0 :         md->cb = trim_clear_cb;
     322           0 :         md->owner.cb_ctx = mngt;
     323           0 :         ftl_md_clear(md, 0, NULL);
     324           0 : }
     325             : 
     326             : void
     327           0 : ftl_mngt_deinit_trim_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     328             : {
     329           0 :         ftl_bitmap_destroy(dev->trim_map);
     330           0 :         dev->trim_map = NULL;
     331             : 
     332           0 :         ftl_md_destroy(dev->trim_map_md, ftl_md_destroy_shm_flags(dev));
     333           0 :         dev->trim_map_md = NULL;
     334             : 
     335           0 :         ftl_mngt_next_step(mngt);
     336           0 : }
     337             : 
     338             : struct ftl_mngt_property_caller_ctx {
     339             :         struct spdk_ftl_dev *dev;
     340             :         struct spdk_jsonrpc_request *request;
     341             :         spdk_ftl_fn cb_fn;
     342             :         void *cb_arg;
     343             :         struct spdk_thread *cb_thread;
     344             :         const char *property;
     345             :         const char *value;
     346             :         size_t value_size;
     347             : };
     348             : 
     349             : static void
     350           0 : ftl_get_properties_cb(void *arg)
     351             : {
     352           0 :         struct ftl_mngt_property_caller_ctx *cctx = arg;
     353             : 
     354           0 :         cctx->cb_fn(cctx->cb_arg, 0);
     355           0 :         free(cctx);
     356           0 : }
     357             : 
     358             : static void
     359           0 : ftl_get_properties_msg(void *arg)
     360             : {
     361           0 :         struct ftl_mngt_property_caller_ctx *cctx = arg;
     362             :         int rc;
     363             : 
     364           0 :         ftl_property_dump(cctx->dev, cctx->request);
     365           0 :         rc = spdk_thread_send_msg(cctx->cb_thread, ftl_get_properties_cb, cctx);
     366           0 :         ftl_bug(rc);
     367           0 : }
     368             : 
     369             : int
     370           0 : spdk_ftl_get_properties(struct spdk_ftl_dev *dev, struct spdk_jsonrpc_request *request,
     371             :                         spdk_ftl_fn cb_fn, void *cb_arg)
     372             : {
     373             :         int rc;
     374           0 :         struct ftl_mngt_property_caller_ctx *ctx = calloc(1, sizeof(*ctx));
     375             : 
     376           0 :         if (ctx == NULL) {
     377           0 :                 return -ENOMEM;
     378             :         }
     379           0 :         ctx->dev = dev;
     380           0 :         ctx->request = request;
     381           0 :         ctx->cb_fn = cb_fn;
     382           0 :         ctx->cb_arg = cb_arg;
     383           0 :         ctx->cb_thread = spdk_get_thread();
     384             : 
     385           0 :         rc = spdk_thread_send_msg(dev->core_thread, ftl_get_properties_msg, ctx);
     386           0 :         if (rc) {
     387           0 :                 free(ctx);
     388           0 :                 return rc;
     389             :         }
     390             : 
     391           0 :         return 0;
     392             : }
     393             : 
     394             : struct ftl_set_property_process_ctx {
     395             :         void *value;
     396             :         size_t value_size;
     397             : };
     398             : 
     399             : static void
     400           0 : ftl_mngt_set_property_decode(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     401             : {
     402           0 :         struct ftl_set_property_process_ctx *pctx = ftl_mngt_get_process_ctx(mngt);
     403           0 :         struct ftl_mngt_property_caller_ctx *cctx = ftl_mngt_get_caller_ctx(mngt);
     404             : 
     405           0 :         if (ftl_property_decode(dev, cctx->property, cctx->value, cctx->value_size,
     406             :                                 &pctx->value, &pctx->value_size)) {
     407           0 :                 ftl_mngt_fail_step(mngt);
     408             :         } else {
     409           0 :                 ftl_mngt_next_step(mngt);
     410             :         }
     411           0 : }
     412             : 
     413             : static void
     414           0 : ftl_mngt_set_property(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     415             : {
     416           0 :         struct ftl_set_property_process_ctx *pctx = ftl_mngt_get_process_ctx(mngt);
     417           0 :         struct ftl_mngt_property_caller_ctx *cctx = ftl_mngt_get_caller_ctx(mngt);
     418             : 
     419           0 :         if (ftl_property_set(dev, mngt, cctx->property, pctx->value, pctx->value_size)) {
     420           0 :                 ftl_mngt_fail_step(mngt);
     421             :         }
     422           0 : }
     423             : 
     424             : static void
     425           0 : ftl_mngt_set_property_cleanup(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     426             : {
     427           0 :         struct ftl_set_property_process_ctx *pctx = ftl_mngt_get_process_ctx(mngt);
     428           0 :         free(pctx->value);
     429           0 :         pctx->value = NULL;
     430           0 :         pctx->value_size = 0;
     431           0 :         ftl_mngt_next_step(mngt);
     432           0 : }
     433             : 
     434             : static const struct ftl_mngt_process_desc desc_set_property = {
     435             :         .name = "Set FTL property",
     436             :         .ctx_size = sizeof(struct ftl_set_property_process_ctx),
     437             :         .steps = {
     438             :                 {
     439             :                         .name = "Decode property",
     440             :                         .action = ftl_mngt_set_property_decode,
     441             :                         .cleanup = ftl_mngt_set_property_cleanup
     442             :                 },
     443             :                 {
     444             :                         .name = "Set property",
     445             :                         .action = ftl_mngt_set_property,
     446             :                         .cleanup = ftl_mngt_set_property_cleanup
     447             :                 },
     448             :                 {
     449             :                         .name = "Property setting cleanup",
     450             :                         .action = ftl_mngt_set_property_cleanup,
     451             :                 },
     452             :                 {}
     453             :         }
     454             : };
     455             : 
     456             : static void
     457           0 : ftl_mngt_property_caller_cb(struct spdk_ftl_dev *dev, void *ctx, int status)
     458             : {
     459           0 :         struct ftl_mngt_property_caller_ctx *cctx = ctx;
     460             : 
     461           0 :         cctx->cb_fn(cctx->cb_arg, status);
     462           0 :         free(cctx);
     463           0 : }
     464             : 
     465             : int
     466           0 : spdk_ftl_set_property(struct spdk_ftl_dev *dev,
     467             :                       const char *property, const char *value, size_t value_size,
     468             :                       spdk_ftl_fn cb_fn, void *cb_arg)
     469             : {
     470             :         int rc;
     471           0 :         struct ftl_mngt_property_caller_ctx *cctx = calloc(1, sizeof(*cctx));
     472             : 
     473           0 :         if (cctx == NULL) {
     474           0 :                 return -EAGAIN;
     475             :         }
     476           0 :         cctx->cb_fn = cb_fn;
     477           0 :         cctx->cb_arg = cb_arg;
     478           0 :         cctx->property = property;
     479           0 :         cctx->value = value;
     480           0 :         cctx->value_size = value_size;
     481             : 
     482           0 :         rc = ftl_mngt_process_execute(dev, &desc_set_property, ftl_mngt_property_caller_cb, cctx);
     483           0 :         if (rc) {
     484           0 :                 free(cctx);
     485             :         }
     486             : 
     487           0 :         return rc;
     488             : }

Generated by: LCOV version 1.15