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 227 0.0 %
Date: 2024-07-14 17:38:19 Functions: 0 29 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, struct ftl_md *md, int status)
     146             : {
     147           0 :         struct ftl_mngt_process *mngt = md->owner.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 :         struct ftl_layout_region *region = ftl_layout_region_get(dev, FTL_LAYOUT_REGION_TYPE_DATA_NVC);
     161           0 :         struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_DATA_NVC];
     162           0 :         union ftl_md_vss vss;
     163             : 
     164           0 :         FTL_NOTICELOG(dev, "First startup needs to scrub nv cache data region, this may take some time.\n");
     165           0 :         FTL_NOTICELOG(dev, "Scrubbing %lluGiB\n", region->current.blocks * FTL_BLOCK_SIZE / GiB);
     166             : 
     167             :         /* Need to scrub user data, so in case of dirty shutdown the recovery won't
     168             :          * pull in data during open chunks recovery from any previous instance (since during short
     169             :          * tests it's very likely that chunks seq_id will be in line between new head md and old VSS)
     170             :          */
     171           0 :         md->cb = user_clear_cb;
     172           0 :         md->owner.cb_ctx = mngt;
     173             : 
     174           0 :         vss.version.md_version = region->current.version;
     175           0 :         vss.nv_cache.lba = FTL_ADDR_INVALID;
     176           0 :         ftl_md_clear(md, 0, &vss);
     177           0 : }
     178             : 
     179             : void
     180           0 : ftl_mngt_finalize_startup(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     181             : {
     182           0 :         if (ftl_bitmap_find_first_set(dev->unmap_map, 0, UINT64_MAX) != UINT64_MAX) {
     183           0 :                 dev->unmap_in_progress = true;
     184             :         }
     185             : 
     186           0 :         ftl_property_register(dev, "superblock_version", &dev->sb->header.version,
     187             :                               sizeof(dev->sb->header.version), NULL, NULL,
     188             :                               ftl_property_dump_uint64, NULL, NULL, false);
     189             : 
     190             :         /* Clear the limit applications as they're incremented incorrectly by
     191             :          * the initialization code.
     192             :          */
     193           0 :         memset(dev->stats.limits, 0, sizeof(dev->stats.limits));
     194           0 :         dev->initialized = 1;
     195           0 :         dev->sb_shm->shm_ready = true;
     196             : 
     197           0 :         ftl_l2p_resume(dev);
     198           0 :         ftl_reloc_resume(dev->reloc);
     199           0 :         ftl_writer_resume(&dev->writer_user);
     200           0 :         ftl_writer_resume(&dev->writer_gc);
     201           0 :         ftl_nv_cache_resume(&dev->nv_cache);
     202             : 
     203           0 :         ftl_mngt_next_step(mngt);
     204           0 : }
     205             : 
     206             : void
     207           0 : ftl_mngt_start_core_poller(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     208             : {
     209           0 :         dev->core_poller = SPDK_POLLER_REGISTER(ftl_core_poller, dev, 0);
     210           0 :         if (!dev->core_poller) {
     211           0 :                 FTL_ERRLOG(dev, "Unable to register core poller\n");
     212           0 :                 ftl_mngt_fail_step(mngt);
     213           0 :                 return;
     214             :         }
     215             : 
     216           0 :         ftl_mngt_next_step(mngt);
     217             : }
     218             : 
     219             : void
     220           0 : ftl_mngt_stop_core_poller(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     221             : {
     222           0 :         dev->halt = true;
     223             : 
     224           0 :         if (dev->core_poller) {
     225           0 :                 ftl_mngt_continue_step(mngt);
     226             :         } else {
     227           0 :                 ftl_mngt_next_step(mngt);
     228             :         }
     229           0 : }
     230             : 
     231             : void
     232           0 : ftl_mngt_dump_stats(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     233             : {
     234           0 :         ftl_dev_dump_bands(dev);
     235           0 :         ftl_dev_dump_stats(dev);
     236           0 :         ftl_mngt_next_step(mngt);
     237           0 : }
     238             : 
     239             : void
     240           0 : ftl_mngt_init_vld_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     241             : {
     242           0 :         struct ftl_md *valid_map_md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_VALID_MAP];
     243             : 
     244           0 :         dev->valid_map = ftl_bitmap_create(ftl_md_get_buffer(valid_map_md),
     245             :                                            ftl_md_get_buffer_size(valid_map_md));
     246           0 :         if (!dev->valid_map) {
     247           0 :                 FTL_ERRLOG(dev, "Failed to create valid map\n");
     248           0 :                 ftl_mngt_fail_step(mngt);
     249           0 :                 return;
     250             :         }
     251             : 
     252           0 :         ftl_mngt_next_step(mngt);
     253             : }
     254             : 
     255             : void
     256           0 : ftl_mngt_deinit_vld_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     257             : {
     258           0 :         if (dev->valid_map) {
     259           0 :                 ftl_bitmap_destroy(dev->valid_map);
     260           0 :                 dev->valid_map = NULL;
     261             :         }
     262             : 
     263           0 :         ftl_mngt_next_step(mngt);
     264           0 : }
     265             : void
     266           0 : ftl_mngt_init_unmap_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     267             : {
     268           0 :         uint64_t num_l2p_pages = spdk_divide_round_up(dev->num_lbas, dev->layout.l2p.lbas_in_page);
     269           0 :         uint64_t map_blocks = ftl_bitmap_bits_to_blocks(num_l2p_pages);
     270             : 
     271           0 :         dev->unmap_map_md = ftl_md_create(dev,
     272             :                                           map_blocks,
     273             :                                           0,
     274             :                                           "trim_bitmap",
     275             :                                           ftl_md_create_shm_flags(dev), NULL);
     276             : 
     277           0 :         if (!dev->unmap_map_md) {
     278           0 :                 FTL_ERRLOG(dev, "Failed to create trim bitmap md\n");
     279           0 :                 ftl_mngt_fail_step(mngt);
     280           0 :                 return;
     281             :         }
     282             : 
     283           0 :         dev->unmap_map = ftl_bitmap_create(ftl_md_get_buffer(dev->unmap_map_md),
     284             :                                            ftl_md_get_buffer_size(dev->unmap_map_md));
     285             : 
     286           0 :         if (!dev->unmap_map) {
     287           0 :                 FTL_ERRLOG(dev, "Failed to create unmap map\n");
     288           0 :                 ftl_mngt_fail_step(mngt);
     289           0 :                 return;
     290             :         }
     291             : 
     292           0 :         ftl_mngt_next_step(mngt);
     293             : }
     294             : 
     295             : static void
     296           0 : unmap_clear_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
     297             : {
     298           0 :         struct ftl_mngt_process *mngt = md->owner.cb_ctx;
     299             : 
     300           0 :         if (status) {
     301           0 :                 FTL_ERRLOG(dev, "ERROR of clearing trim unmap\n");
     302           0 :                 ftl_mngt_fail_step(mngt);
     303             :         } else {
     304           0 :                 ftl_mngt_next_step(mngt);
     305             :         }
     306           0 : }
     307             : 
     308             : void
     309           0 : ftl_mngt_unmap_clear(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     310             : {
     311           0 :         struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_TRIM_MD];
     312             : 
     313           0 :         md->cb = unmap_clear_cb;
     314           0 :         md->owner.cb_ctx = mngt;
     315             : 
     316           0 :         ftl_md_clear(md, 0, NULL);
     317           0 : }
     318             : 
     319             : void
     320           0 : ftl_mngt_deinit_unmap_map(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     321             : {
     322           0 :         ftl_bitmap_destroy(dev->unmap_map);
     323           0 :         dev->unmap_map = NULL;
     324             : 
     325           0 :         ftl_md_destroy(dev->unmap_map_md, ftl_md_destroy_shm_flags(dev));
     326           0 :         dev->unmap_map_md = NULL;
     327             : 
     328           0 :         ftl_mngt_next_step(mngt);
     329           0 : }
     330             : 
     331             : struct ftl_mngt_property_caller_ctx {
     332             :         struct spdk_ftl_dev *dev;
     333             :         struct spdk_jsonrpc_request *request;
     334             :         spdk_ftl_fn cb_fn;
     335             :         void *cb_arg;
     336             :         struct spdk_thread *cb_thread;
     337             :         const char *property;
     338             :         const char *value;
     339             :         size_t value_size;
     340             : };
     341             : 
     342             : static void
     343           0 : ftl_get_properties_cb(void *arg)
     344             : {
     345           0 :         struct ftl_mngt_property_caller_ctx *cctx = arg;
     346             : 
     347           0 :         cctx->cb_fn(cctx->cb_arg, 0);
     348           0 :         free(cctx);
     349           0 : }
     350             : 
     351             : static void
     352           0 : ftl_get_properties_msg(void *arg)
     353             : {
     354           0 :         struct ftl_mngt_property_caller_ctx *cctx = arg;
     355             :         int rc;
     356             : 
     357           0 :         ftl_property_dump(cctx->dev, cctx->request);
     358           0 :         rc = spdk_thread_send_msg(cctx->cb_thread, ftl_get_properties_cb, cctx);
     359           0 :         ftl_bug(rc);
     360           0 : }
     361             : 
     362             : int
     363           0 : spdk_ftl_get_properties(struct spdk_ftl_dev *dev, struct spdk_jsonrpc_request *request,
     364             :                         spdk_ftl_fn cb_fn, void *cb_arg)
     365             : {
     366             :         int rc;
     367           0 :         struct ftl_mngt_property_caller_ctx *ctx = calloc(1, sizeof(*ctx));
     368             : 
     369           0 :         if (ctx == NULL) {
     370           0 :                 return -ENOMEM;
     371             :         }
     372           0 :         ctx->dev = dev;
     373           0 :         ctx->request = request;
     374           0 :         ctx->cb_fn = cb_fn;
     375           0 :         ctx->cb_arg = cb_arg;
     376           0 :         ctx->cb_thread = spdk_get_thread();
     377             : 
     378           0 :         rc = spdk_thread_send_msg(dev->core_thread, ftl_get_properties_msg, ctx);
     379           0 :         if (rc) {
     380           0 :                 free(ctx);
     381           0 :                 return rc;
     382             :         }
     383             : 
     384           0 :         return 0;
     385             : }
     386             : 
     387             : struct ftl_set_property_process_ctx {
     388             :         void *value;
     389             :         size_t value_size;
     390             : };
     391             : 
     392             : static void
     393           0 : ftl_mngt_set_property_decode(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     394             : {
     395           0 :         struct ftl_set_property_process_ctx *pctx = ftl_mngt_get_process_ctx(mngt);
     396           0 :         struct ftl_mngt_property_caller_ctx *cctx = ftl_mngt_get_caller_ctx(mngt);
     397             : 
     398           0 :         if (ftl_property_decode(dev, cctx->property, cctx->value, cctx->value_size,
     399             :                                 &pctx->value, &pctx->value_size)) {
     400           0 :                 ftl_mngt_fail_step(mngt);
     401             :         } else {
     402           0 :                 ftl_mngt_next_step(mngt);
     403             :         }
     404           0 : }
     405             : 
     406             : static void
     407           0 : ftl_mngt_set_property(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     408             : {
     409           0 :         struct ftl_set_property_process_ctx *pctx = ftl_mngt_get_process_ctx(mngt);
     410           0 :         struct ftl_mngt_property_caller_ctx *cctx = ftl_mngt_get_caller_ctx(mngt);
     411             : 
     412           0 :         if (ftl_property_set(dev, mngt, cctx->property, pctx->value, pctx->value_size)) {
     413           0 :                 ftl_mngt_fail_step(mngt);
     414             :         }
     415           0 : }
     416             : 
     417             : static void
     418           0 : ftl_mngt_set_property_cleanup(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     419             : {
     420           0 :         struct ftl_set_property_process_ctx *pctx = ftl_mngt_get_process_ctx(mngt);
     421           0 :         free(pctx->value);
     422           0 :         pctx->value = NULL;
     423           0 :         pctx->value_size = 0;
     424           0 :         ftl_mngt_next_step(mngt);
     425           0 : }
     426             : 
     427             : static const struct ftl_mngt_process_desc desc_set_property = {
     428             :         .name = "Set FTL property",
     429             :         .ctx_size = sizeof(struct ftl_set_property_process_ctx),
     430             :         .steps = {
     431             :                 {
     432             :                         .name = "Decode property",
     433             :                         .action = ftl_mngt_set_property_decode,
     434             :                         .cleanup = ftl_mngt_set_property_cleanup
     435             :                 },
     436             :                 {
     437             :                         .name = "Set property",
     438             :                         .action = ftl_mngt_set_property,
     439             :                         .cleanup = ftl_mngt_set_property_cleanup
     440             :                 },
     441             :                 {
     442             :                         .name = "Property setting cleanup",
     443             :                         .action = ftl_mngt_set_property_cleanup,
     444             :                 },
     445             :                 {}
     446             :         }
     447             : };
     448             : 
     449             : static void
     450           0 : ftl_mngt_property_caller_cb(struct spdk_ftl_dev *dev, void *ctx, int status)
     451             : {
     452           0 :         struct ftl_mngt_property_caller_ctx *cctx = ctx;
     453             : 
     454           0 :         cctx->cb_fn(cctx->cb_arg, status);
     455           0 :         free(cctx);
     456           0 : }
     457             : 
     458             : int
     459           0 : spdk_ftl_set_property(struct spdk_ftl_dev *dev,
     460             :                       const char *property, const char *value, size_t value_size,
     461             :                       spdk_ftl_fn cb_fn, void *cb_arg)
     462             : {
     463             :         int rc;
     464           0 :         struct ftl_mngt_property_caller_ctx *cctx = calloc(1, sizeof(*cctx));
     465             : 
     466           0 :         if (cctx == NULL) {
     467           0 :                 return -EAGAIN;
     468             :         }
     469           0 :         cctx->cb_fn = cb_fn;
     470           0 :         cctx->cb_arg = cb_arg;
     471           0 :         cctx->property = property;
     472           0 :         cctx->value = value;
     473           0 :         cctx->value_size = value_size;
     474             : 
     475           0 :         rc = ftl_mngt_process_execute(dev, &desc_set_property, ftl_mngt_property_caller_cb, cctx);
     476           0 :         if (rc) {
     477           0 :                 free(cctx);
     478             :         }
     479             : 
     480           0 :         return rc;
     481             : }

Generated by: LCOV version 1.15