LCOV - code coverage report
Current view: top level - spdk/lib/ftl/mngt - ftl_mngt_band.c (source / functions) Hit Total Coverage
Test: Combined Lines: 186 275 67.6 %
Date: 2024-12-09 18:25:38 Functions: 16 18 88.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 67 1056 6.3 %

           Branch data     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_mngt_steps.h"
       8                 :            : #include "ftl_band.h"
       9                 :            : #include "ftl_internal.h"
      10                 :            : 
      11                 :            : static int
      12                 :       2036 : ftl_band_init_md(struct ftl_band *band)
      13                 :            : {
      14   [ #  #  #  # ]:       2036 :         struct spdk_ftl_dev *dev = band->dev;
      15         [ #  # ]:       2036 :         struct ftl_p2l_map *p2l_map = &band->p2l_map;
      16   [ #  #  #  #  :       2036 :         struct ftl_md *band_info_md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_BAND_MD];
             #  #  #  # ]
      17   [ #  #  #  #  :       2036 :         struct ftl_md *valid_map_md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_VALID_MAP];
             #  #  #  # ]
      18   [ #  #  #  # ]:       2036 :         uint64_t band_num_blocks = ftl_get_num_blocks_in_band(band->dev);
      19                 :            :         size_t band_valid_map_bytes;
      20                 :       2036 :         struct ftl_band_md *band_md = ftl_md_get_buffer(band_info_md);
      21                 :            : 
      22   [ -  +  -  + ]:       2036 :         if (band_num_blocks % (ftl_bitmap_buffer_alignment * 8)) {
      23   [ #  #  #  #  :          0 :                 FTL_ERRLOG(dev, "The number of blocks in band is not divisible by bitmap word bits\n");
             #  #  #  # ]
      24                 :          0 :                 return -EINVAL;
      25                 :            :         }
      26         [ #  # ]:       2036 :         band_valid_map_bytes = band_num_blocks / 8;
      27                 :            : 
      28   [ #  #  #  #  :       4072 :         p2l_map->valid = ftl_bitmap_create(ftl_md_get_buffer(valid_map_md) +
                   #  # ]
      29   [ #  #  #  #  :       2036 :                                            band->start_addr / 8, band_valid_map_bytes);
                   #  # ]
      30   [ -  +  #  #  :       2036 :         if (!p2l_map->valid) {
                   #  # ]
      31                 :          0 :                 return -ENOMEM;
      32                 :            :         }
      33                 :            : 
      34   [ #  #  #  #  :       2036 :         band->md = &band_md[band->id];
          #  #  #  #  #  
                      # ]
      35   [ #  #  #  #  :       2036 :         band->md->version = FTL_BAND_VERSION_CURRENT;
             #  #  #  # ]
      36         [ +  - ]:       2036 :         if (!ftl_fast_startup(dev)) {
      37   [ #  #  #  #  :       2036 :                 band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
             #  #  #  # ]
      38                 :          0 :         }
      39                 :            : 
      40                 :       2036 :         return 0;
      41                 :          0 : }
      42                 :            : 
      43                 :            : static int
      44                 :         22 : ftl_dev_init_bands(struct spdk_ftl_dev *dev)
      45                 :            : {
      46                 :            :         struct ftl_band *band;
      47                 :            :         uint64_t i, blocks, md_blocks, md_bands;
      48                 :            : 
      49                 :            :         /* Calculate initial number of bands */
      50   [ #  #  #  # ]:         22 :         blocks = spdk_bdev_get_num_blocks(spdk_bdev_desc_get_bdev(dev->base_bdev_desc));
      51   [ -  +  #  #  :         22 :         dev->num_bands = blocks / ftl_get_num_blocks_in_band(dev);
                   #  # ]
      52                 :            : 
      53                 :            :         /* Calculate number of bands considering base device metadata size requirement */
      54                 :         22 :         md_blocks = ftl_layout_base_md_blocks(dev);
      55   [ #  #  #  # ]:         22 :         md_bands = spdk_divide_round_up(md_blocks, dev->num_blocks_in_band);
      56                 :            : 
      57   [ +  -  #  #  :         22 :         if (dev->num_bands > md_bands) {
                   #  # ]
      58                 :            :                 /* Save a band worth of space for metadata */
      59   [ #  #  #  # ]:         22 :                 dev->num_bands -= md_bands;
      60                 :          0 :         } else {
      61   [ #  #  #  #  :          0 :                 FTL_ERRLOG(dev, "Base device too small to store metadata\n");
             #  #  #  # ]
      62                 :          0 :                 return -1;
      63                 :            :         }
      64                 :            : 
      65   [ #  #  #  #  :         22 :         TAILQ_INIT(&dev->free_bands);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
      66   [ #  #  #  #  :         22 :         TAILQ_INIT(&dev->shut_bands);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
      67                 :            : 
      68   [ #  #  #  # ]:         22 :         dev->num_free = 0;
      69   [ #  #  #  # ]:         22 :         dev->bands = calloc(ftl_get_num_bands(dev), sizeof(*dev->bands));
      70   [ -  +  #  #  :         22 :         if (!dev->bands) {
                   #  # ]
      71                 :          0 :                 return -ENOMEM;
      72                 :            :         }
      73                 :            : 
      74         [ +  + ]:       2060 :         for (i = 0; i < ftl_get_num_bands(dev); ++i) {
      75   [ #  #  #  #  :       2038 :                 band = &dev->bands[i];
                   #  # ]
      76   [ #  #  #  # ]:       2038 :                 band->id = i;
      77   [ #  #  #  # ]:       2038 :                 band->dev = dev;
      78                 :            : 
      79                 :            :                 /* Adding to shut_bands is necessary - see ftl_restore_band_close_cb() */
      80   [ #  #  #  #  :       2038 :                 TAILQ_INSERT_TAIL(&dev->shut_bands, band, queue_entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
      81                 :          0 :         }
      82                 :            : 
      83                 :         22 :         return 0;
      84                 :          0 : }
      85                 :            : 
      86                 :            : static int
      87                 :         22 : ftl_dev_init_bands_md(struct spdk_ftl_dev *dev)
      88                 :            : {
      89                 :            :         uint64_t i;
      90                 :         22 :         int rc = 0;
      91                 :            : 
      92         [ +  + ]:       2058 :         for (i = 0; i < ftl_get_num_bands(dev); ++i) {
      93   [ #  #  #  #  :       2036 :                 rc = ftl_band_init_md(&dev->bands[i]);
                   #  # ]
      94         [ -  + ]:       2036 :                 if (rc) {
      95   [ #  #  #  #  :          0 :                         FTL_ERRLOG(dev, "Failed to initialize metadata structures for band [%lu]\n", i);
             #  #  #  # ]
      96                 :          0 :                         break;
      97                 :            :                 }
      98                 :          0 :         }
      99                 :            : 
     100                 :         22 :         return rc;
     101                 :            : }
     102                 :            : 
     103                 :            : static void
     104                 :         22 : ftl_dev_deinit_bands(struct spdk_ftl_dev *dev)
     105                 :            : {
     106   [ #  #  #  # ]:         22 :         free(dev->bands);
     107                 :         22 : }
     108                 :            : 
     109                 :            : static void
     110                 :         22 : ftl_dev_deinit_bands_md(struct spdk_ftl_dev *dev)
     111                 :            : {
     112   [ +  -  #  #  :         22 :         if (dev->bands) {
                   #  # ]
     113                 :            :                 uint64_t i;
     114   [ +  +  #  #  :       2058 :                 for (i = 0; i < dev->num_bands; ++i) {
                   #  # ]
     115   [ #  #  #  #  :       2036 :                         struct ftl_band *band = &dev->bands[i];
                   #  # ]
     116                 :            : 
     117   [ #  #  #  #  :       2036 :                         ftl_bitmap_destroy(band->p2l_map.valid);
                   #  # ]
     118   [ #  #  #  #  :       2036 :                         band->p2l_map.valid = NULL;
                   #  # ]
     119                 :            : 
     120   [ #  #  #  # ]:       2036 :                         band->md = NULL;
     121                 :          0 :                 }
     122                 :          0 :         }
     123                 :         22 : }
     124                 :            : 
     125                 :            : void
     126                 :         22 : ftl_mngt_init_bands(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     127                 :            : {
     128         [ -  + ]:         22 :         if (ftl_dev_init_bands(dev)) {
     129                 :          0 :                 ftl_mngt_fail_step(mngt);
     130                 :          0 :         } else {
     131                 :         22 :                 ftl_mngt_next_step(mngt);
     132                 :            :         }
     133                 :         22 : }
     134                 :            : 
     135                 :            : void
     136                 :         22 : ftl_mngt_init_bands_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     137                 :            : {
     138         [ -  + ]:         22 :         if (ftl_dev_init_bands_md(dev)) {
     139                 :          0 :                 ftl_mngt_fail_step(mngt);
     140                 :          0 :         } else {
     141                 :         22 :                 ftl_mngt_next_step(mngt);
     142                 :            :         }
     143                 :         22 : }
     144                 :            : 
     145                 :            : void
     146                 :         22 : ftl_mngt_deinit_bands(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     147                 :            : {
     148                 :         22 :         ftl_dev_deinit_bands(dev);
     149                 :         22 :         ftl_mngt_next_step(mngt);
     150                 :         22 : }
     151                 :            : 
     152                 :            : void
     153                 :         22 : ftl_mngt_deinit_bands_md(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     154                 :            : {
     155                 :         22 :         ftl_dev_deinit_bands_md(dev);
     156                 :         22 :         ftl_mngt_next_step(mngt);
     157                 :         22 : }
     158                 :            : 
     159                 :            : /*
     160                 :            :  * For grouping multiple logical bands (1GiB) to make any IOs more sequential from the drive's
     161                 :            :  * perspective. Improves WAF.
     162                 :            :  */
     163                 :            : #define BASE_BDEV_RECLAIM_UNIT_SIZE (72 * GiB)
     164                 :            : 
     165                 :            : static void
     166                 :         22 : decorate_bands(struct spdk_ftl_dev *dev)
     167                 :            : {
     168                 :            :         struct ftl_band *band;
     169                 :         22 :         uint64_t i, num_to_drop, phys_id = 0;
     170                 :            :         uint64_t num_blocks, num_bands;
     171                 :         22 :         uint64_t num_blocks_in_band = ftl_get_num_blocks_in_band(dev);
     172         [ #  # ]:         22 :         uint64_t reclaim_unit_num_blocks = BASE_BDEV_RECLAIM_UNIT_SIZE / FTL_BLOCK_SIZE;
     173                 :         22 :         uint32_t num_logical_in_phys = 2;
     174                 :            : 
     175   [ -  +  -  +  :         22 :         assert(reclaim_unit_num_blocks % num_blocks_in_band == 0);
                   #  # ]
     176                 :            : 
     177   [ #  #  #  # ]:         22 :         num_blocks = spdk_bdev_get_num_blocks(spdk_bdev_desc_get_bdev(dev->base_bdev_desc));
     178                 :            : 
     179                 :            :         /* For base bdev bigger than 1TB take reclaim uint size for grouping GC bands */
     180   [ -  +  #  # ]:         22 :         if (num_blocks > (TiB / FTL_BLOCK_SIZE)) {
     181   [ #  #  #  # ]:          0 :                 assert(reclaim_unit_num_blocks < num_blocks);
     182         [ #  # ]:          0 :                 num_logical_in_phys = reclaim_unit_num_blocks / num_blocks_in_band;
     183                 :          0 :         }
     184                 :            : 
     185         [ -  + ]:         22 :         num_to_drop = ftl_get_num_bands(dev) % num_logical_in_phys;
     186                 :            : 
     187                 :         22 :         i = 0;
     188         [ +  + ]:       2058 :         while (i < ftl_get_num_bands(dev) - num_to_drop) {
     189   [ #  #  #  #  :       2036 :                 band = &dev->bands[i];
                   #  # ]
     190                 :            : 
     191   [ #  #  #  # ]:       2036 :                 band->phys_id = phys_id;
     192                 :       2036 :                 i++;
     193   [ -  +  +  + ]:       2036 :                 if (i % num_logical_in_phys == 0) {
     194                 :       1018 :                         phys_id++;
     195                 :          0 :                 }
     196                 :            :         }
     197                 :            : 
     198                 :            :         /* Mark not aligned logical bands as broken */
     199                 :         22 :         num_bands = ftl_get_num_bands(dev);
     200         [ +  + ]:         24 :         while (i < num_bands) {
     201   [ #  #  #  #  :          2 :                 band = &dev->bands[i];
                   #  # ]
     202         [ #  # ]:          2 :                 dev->num_bands--;
     203   [ -  +  #  #  :          2 :                 TAILQ_REMOVE(&dev->shut_bands, band, queue_entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     204                 :          2 :                 i++;
     205                 :            :         }
     206                 :            : 
     207   [ #  #  #  # ]:         22 :         dev->num_logical_bands_in_physical = num_logical_in_phys;
     208                 :         22 : }
     209                 :            : 
     210                 :            : void
     211                 :         22 : ftl_mngt_decorate_bands(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     212                 :            : {
     213                 :         22 :         decorate_bands(dev);
     214                 :         22 :         ftl_mngt_next_step(mngt);
     215                 :         22 : }
     216                 :            : 
     217                 :            : void
     218                 :         22 : ftl_mngt_initialize_band_address(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     219                 :            : {
     220                 :            :         struct ftl_band *band;
     221   [ #  #  #  #  :         22 :         struct ftl_md *data_md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_DATA_BASE];
             #  #  #  # ]
     222                 :            :         uint64_t i;
     223                 :            : 
     224         [ +  + ]:       2058 :         for (i = 0; i < ftl_get_num_bands(dev); i++) {
     225   [ #  #  #  #  :       2036 :                 band = &dev->bands[i];
                   #  # ]
     226   [ #  #  #  #  :       2036 :                 band->start_addr = data_md->region->current.offset + i * dev->num_blocks_in_band;
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     227   [ #  #  #  # ]:       2036 :                 band->tail_md_addr = ftl_band_tail_md_addr(band);
     228                 :          0 :         }
     229                 :            : 
     230                 :         22 :         ftl_mngt_next_step(mngt);
     231                 :         22 : }
     232                 :            : 
     233                 :            : void
     234                 :         23 : ftl_recover_max_seq(struct spdk_ftl_dev *dev)
     235                 :            : {
     236                 :            :         struct ftl_band *band;
     237                 :         23 :         uint64_t band_close_seq_id = 0, band_open_seq_id = 0;
     238                 :         23 :         uint64_t chunk_close_seq_id = 0, chunk_open_seq_id = 0;
     239                 :         23 :         uint64_t max = 0;
     240                 :            : 
     241   [ +  +  #  #  :        451 :         TAILQ_FOREACH(band, &dev->shut_bands, queue_entry) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     242   [ #  #  #  #  :        428 :                 band_open_seq_id = spdk_max(band_open_seq_id, band->md->seq);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     243   [ #  #  #  #  :        428 :                 band_close_seq_id = spdk_max(band_close_seq_id, band->md->close_seq_id);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     244                 :          0 :         }
     245         [ #  # ]:         23 :         ftl_nv_cache_get_max_seq_id(&dev->nv_cache, &chunk_open_seq_id, &chunk_close_seq_id);
     246                 :            : 
     247                 :            : 
     248   [ #  #  #  #  :         23 :         dev->nv_cache.last_seq_id = chunk_close_seq_id;
                   #  # ]
     249   [ #  #  #  #  :         23 :         dev->writer_gc.last_seq_id = band_close_seq_id;
                   #  # ]
     250   [ #  #  #  #  :         23 :         dev->writer_user.last_seq_id = band_close_seq_id;
                   #  # ]
     251                 :            : 
     252         [ #  # ]:         23 :         max = spdk_max(max, band_open_seq_id);
     253         [ #  # ]:         23 :         max = spdk_max(max, band_close_seq_id);
     254         [ #  # ]:         23 :         max = spdk_max(max, chunk_open_seq_id);
     255         [ #  # ]:         23 :         max = spdk_max(max, chunk_close_seq_id);
     256                 :            : 
     257   [ #  #  #  #  :         23 :         dev->sb->seq_id = max;
             #  #  #  # ]
     258                 :         23 : }
     259                 :            : 
     260                 :            : static int
     261                 :          0 : _band_cmp(const void *_a, const void *_b)
     262                 :            : {
     263                 :            :         struct ftl_band *a, *b;
     264                 :            : 
     265         [ #  # ]:          0 :         a = *((struct ftl_band **)_a);
     266         [ #  # ]:          0 :         b = *((struct ftl_band **)_b);
     267                 :            : 
     268   [ #  #  #  #  :          0 :         return a->md->seq - b->md->seq;
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     269                 :            : }
     270                 :            : 
     271                 :            : static struct ftl_band *
     272                 :          0 : next_high_prio_band(struct spdk_ftl_dev *dev)
     273                 :            : {
     274                 :          0 :         struct ftl_band *result = NULL, *band;
     275                 :          0 :         uint64_t validity = UINT64_MAX;
     276                 :            : 
     277   [ #  #  #  #  :          0 :         TAILQ_FOREACH(band, &dev->shut_bands, queue_entry) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     278   [ #  #  #  #  :          0 :                 if (band->p2l_map.num_valid < validity) {
             #  #  #  # ]
     279                 :          0 :                         result = band;
     280   [ #  #  #  #  :          0 :                         validity = result->p2l_map.num_valid;
                   #  # ]
     281                 :          0 :                 }
     282                 :          0 :         }
     283                 :            : 
     284                 :          0 :         return result;
     285                 :            : }
     286                 :            : 
     287                 :            : static int
     288                 :         22 : finalize_init_gc(struct spdk_ftl_dev *dev)
     289                 :            : {
     290                 :            :         struct ftl_band *band;
     291                 :            :         uint64_t free_blocks, blocks_to_move;
     292                 :            : 
     293                 :         22 :         ftl_band_init_gc_iter(dev);
     294   [ #  #  #  #  :         22 :         dev->sb_shm->gc_info.band_id_high_prio = FTL_BAND_ID_INVALID;
          #  #  #  #  #  
                      # ]
     295                 :            : 
     296   [ -  +  #  #  :         22 :         if (0 == dev->num_free) {
                   #  # ]
     297                 :            :                 /* Get number of available blocks in writer */
     298         [ #  # ]:          0 :                 free_blocks = ftl_writer_get_free_blocks(&dev->writer_gc);
     299                 :            : 
     300                 :            :                 /*
     301                 :            :                  * First, check a band candidate to GC
     302                 :            :                  */
     303                 :          0 :                 band = ftl_band_search_next_to_reloc(dev);
     304   [ #  #  #  # ]:          0 :                 ftl_bug(NULL == band);
     305   [ #  #  #  #  :          0 :                 blocks_to_move = band->p2l_map.num_valid;
                   #  # ]
     306         [ #  # ]:          0 :                 if (blocks_to_move <= free_blocks) {
     307                 :            :                         /* This GC band can be moved */
     308                 :          0 :                         return 0;
     309                 :            :                 }
     310                 :            : 
     311                 :            :                 /*
     312                 :            :                  * The GC candidate cannot be moved because no enough space. We need to find
     313                 :            :                  * another band.
     314                 :            :                  */
     315                 :          0 :                 band = next_high_prio_band(dev);
     316   [ #  #  #  # ]:          0 :                 ftl_bug(NULL == band);
     317                 :            : 
     318   [ #  #  #  #  :          0 :                 if (band->p2l_map.num_valid > free_blocks) {
             #  #  #  # ]
     319   [ #  #  #  #  :          0 :                         FTL_ERRLOG(dev, "CRITICAL ERROR, no more free bands and cannot start\n");
             #  #  #  # ]
     320                 :          0 :                         return -1;
     321                 :            :                 } else {
     322                 :            :                         /* GC needs to start using this band */
     323   [ #  #  #  #  :          0 :                         dev->sb_shm->gc_info.band_id_high_prio = band->id;
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     324                 :            :                 }
     325                 :          0 :         }
     326                 :            : 
     327                 :         22 :         return 0;
     328                 :          0 : }
     329                 :            : 
     330                 :            : static void
     331                 :          3 : ftl_property_dump_base_dev(struct spdk_ftl_dev *dev, const struct ftl_property *property,
     332                 :            :                            struct spdk_json_write_ctx *w)
     333                 :            : {
     334                 :            :         uint64_t i;
     335                 :            :         struct ftl_band *band;
     336                 :            : 
     337                 :          3 :         spdk_json_write_named_array_begin(w, "bands");
     338   [ +  +  #  #  :         57 :         for (i = 0, band = dev->bands; i < ftl_get_num_bands(dev); i++, band++) {
             #  #  #  # ]
     339                 :         54 :                 spdk_json_write_object_begin(w);
     340                 :         54 :                 spdk_json_write_named_uint64(w, "id", i);
     341                 :         54 :                 spdk_json_write_named_string(w, "state", ftl_band_get_state_name(band));
     342                 :         54 :                 spdk_json_write_named_double(w, "validity", 1.0 - ftl_band_invalidity(band));
     343                 :         54 :                 spdk_json_write_object_end(w);
     344                 :          0 :         }
     345                 :          3 :         spdk_json_write_array_end(w);
     346                 :          3 : }
     347                 :            : 
     348                 :            : void
     349                 :         22 : ftl_mngt_finalize_init_bands(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
     350                 :            : {
     351                 :         22 :         struct ftl_band *band, *temp_band, *open_bands[FTL_MAX_OPEN_BANDS];
     352                 :         22 :         struct ftl_writer *writer = NULL;
     353                 :         22 :         uint64_t i, num_open = 0, num_shut = 0;
     354                 :            :         uint64_t offset;
     355                 :         22 :         bool fast_startup = ftl_fast_startup(dev);
     356                 :            : 
     357                 :         22 :         ftl_recover_max_seq(dev);
     358                 :         22 :         ftl_property_register(dev, "base_device", NULL, 0, NULL, NULL, ftl_property_dump_base_dev, NULL,
     359                 :            :                               NULL, true);
     360                 :            : 
     361   [ +  +  #  #  :       1633 :         TAILQ_FOREACH_SAFE(band, &dev->free_bands, queue_entry, temp_band) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     362   [ #  #  #  #  :       1611 :                 band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
             #  #  #  # ]
     363                 :          0 :         }
     364                 :            : 
     365   [ +  +  #  #  :        447 :         TAILQ_FOREACH_SAFE(band, &dev->shut_bands, queue_entry, temp_band) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     366   [ +  +  #  #  :        425 :                 if (band->md->state == FTL_BAND_STATE_OPEN ||
          #  #  #  #  #  
                #  #  # ]
     367   [ -  +  #  #  :        422 :                     band->md->state == FTL_BAND_STATE_FULL) {
             #  #  #  # ]
     368   [ -  +  #  #  :          3 :                         TAILQ_REMOVE(&dev->shut_bands, band, queue_entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     369   [ #  #  #  #  :          3 :                         open_bands[num_open++] = band;
                   #  # ]
     370   [ -  +  #  # ]:          3 :                         assert(num_open <= FTL_MAX_OPEN_BANDS);
     371                 :          3 :                         continue;
     372                 :            :                 }
     373                 :            : 
     374   [ +  +  #  #  :        422 :                 if (dev->conf.mode & SPDK_FTL_MODE_CREATE) {
             #  #  #  # ]
     375   [ +  +  #  #  :        418 :                         TAILQ_REMOVE(&dev->shut_bands, band, queue_entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     376   [ -  +  #  #  :        418 :                         assert(band->md->state == FTL_BAND_STATE_FREE);
          #  #  #  #  #  
                #  #  # ]
     377   [ #  #  #  #  :        418 :                         band->md->state = FTL_BAND_STATE_CLOSED;
             #  #  #  # ]
     378                 :        418 :                         ftl_band_set_state(band, FTL_BAND_STATE_FREE);
     379                 :          0 :                 } else {
     380                 :          4 :                         num_shut++;
     381                 :            :                 }
     382                 :            : 
     383   [ #  #  #  #  :        422 :                 band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
             #  #  #  # ]
     384                 :          0 :         }
     385                 :            : 
     386                 :            :         /* Assign open bands to writers and alloc necessary resources */
     387   [ -  +  -  + ]:         22 :         qsort(open_bands, num_open, sizeof(open_bands[0]), _band_cmp);
     388                 :            : 
     389         [ +  + ]:         25 :         for (i = 0; i < num_open; ++i) {
     390   [ #  #  #  #  :          3 :                 band = open_bands[i];
                   #  # ]
     391                 :            : 
     392   [ +  -  #  #  :          3 :                 if (band->md->type == FTL_BAND_TYPE_COMPACTION) {
          #  #  #  #  #  
                      # ]
     393         [ #  # ]:          3 :                         writer = &dev->writer_user;
     394   [ #  #  #  #  :          0 :                 } else if (band->md->type == FTL_BAND_TYPE_GC) {
          #  #  #  #  #  
                      # ]
     395         [ #  # ]:          0 :                         writer = &dev->writer_gc;
     396                 :          0 :                 } else {
     397         [ #  # ]:          0 :                         assert(false);
     398                 :            :                 }
     399                 :            : 
     400   [ -  +  #  #  :          3 :                 if (band->md->state == FTL_BAND_STATE_FULL) {
          #  #  #  #  #  
                      # ]
     401   [ #  #  #  #  :          0 :                         TAILQ_INSERT_TAIL(&writer->full_bands, band, queue_entry);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     402                 :          0 :                 } else {
     403   [ +  -  #  #  :          3 :                         if (writer->band == NULL) {
                   #  # ]
     404   [ #  #  #  # ]:          3 :                                 writer->band = band;
     405                 :          0 :                         } else {
     406   [ #  #  #  # ]:          0 :                                 writer->next_band = band;
     407                 :            :                         }
     408                 :            :                 }
     409                 :            : 
     410         [ #  # ]:          3 :                 writer->num_bands++;
     411                 :          3 :                 ftl_band_set_owner(band, ftl_writer_band_state_change, writer);
     412                 :            : 
     413   [ -  +  #  # ]:          3 :                 if (fast_startup) {
     414   [ #  #  #  #  :          0 :                         FTL_NOTICELOG(dev, "SHM: band open P2L map df_id 0x%"PRIx64"\n", band->md->df_p2l_map);
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     415         [ #  # ]:          0 :                         if (ftl_band_open_p2l_map(band)) {
     416                 :          0 :                                 ftl_mngt_fail_step(mngt);
     417                 :          0 :                                 return;
     418                 :            :                         }
     419                 :            : 
     420   [ #  #  #  #  :          0 :                         offset = band->md->iter.offset;
          #  #  #  #  #  
                      # ]
     421                 :          0 :                         ftl_band_iter_init(band);
     422                 :          0 :                         ftl_band_iter_set(band, offset);
     423                 :          0 :                         ftl_mngt_p2l_ckpt_restore_shm_clean(band);
     424   [ +  -  #  #  :          3 :                 } else if (dev->sb->clean) {
          #  #  #  #  #  
                      # ]
     425   [ #  #  #  #  :          3 :                         band->md->df_p2l_map = FTL_DF_OBJ_ID_INVALID;
             #  #  #  # ]
     426         [ -  + ]:          3 :                         if (ftl_band_alloc_p2l_map(band)) {
     427                 :          0 :                                 ftl_mngt_fail_step(mngt);
     428                 :          0 :                                 return;
     429                 :            :                         }
     430                 :            : 
     431   [ #  #  #  #  :          3 :                         offset = band->md->iter.offset;
          #  #  #  #  #  
                      # ]
     432                 :          3 :                         ftl_band_iter_init(band);
     433                 :          3 :                         ftl_band_iter_set(band, offset);
     434                 :            : 
     435         [ -  + ]:          3 :                         if (ftl_mngt_p2l_ckpt_restore_clean(band)) {
     436                 :          0 :                                 ftl_mngt_fail_step(mngt);
     437                 :          0 :                                 return;
     438                 :            :                         }
     439                 :          0 :                 }
     440                 :          0 :         }
     441                 :            : 
     442   [ -  +  #  # ]:         22 :         if (fast_startup) {
     443   [ #  #  #  # ]:          0 :                 ftl_mempool_initialize_ext(dev->p2l_pool);
     444                 :          0 :         }
     445                 :            : 
     446                 :            : 
     447                 :            :         /* Recalculate number of free bands */
     448   [ #  #  #  # ]:         22 :         dev->num_free = 0;
     449   [ +  +  #  #  :       2051 :         TAILQ_FOREACH(band, &dev->free_bands, queue_entry) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     450   [ -  +  #  #  :       2029 :                 assert(band->md->state == FTL_BAND_STATE_FREE);
          #  #  #  #  #  
                #  #  # ]
     451         [ #  # ]:       2029 :                 dev->num_free++;
     452                 :          0 :         }
     453                 :         22 :         ftl_apply_limits(dev);
     454                 :            : 
     455   [ -  +  #  #  :         22 :         if ((num_shut + num_open + dev->num_free) != ftl_get_num_bands(dev)) {
                   #  # ]
     456   [ #  #  #  #  :          0 :                 FTL_ERRLOG(dev, "ERROR, band list inconsistent state\n");
             #  #  #  # ]
     457                 :          0 :                 ftl_mngt_fail_step(mngt);
     458                 :          0 :                 return;
     459                 :            :         }
     460                 :            : 
     461         [ -  + ]:         22 :         if (finalize_init_gc(dev)) {
     462                 :          0 :                 ftl_mngt_fail_step(mngt);
     463                 :          0 :         } else {
     464                 :         22 :                 ftl_mngt_next_step(mngt);
     465                 :            :         }
     466                 :          0 : }

Generated by: LCOV version 1.15