LCOV - code coverage report
Current view: top level - lib/ftl/nvc - ftl_nvc_bdev_vss.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 0 92 0.0 %
Date: 2024-11-20 23:57:33 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright 2023 Solidigm All Rights Reserved
       3             :  */
       4             : 
       5             : #include "ftl_nvc_dev.h"
       6             : #include "ftl_core.h"
       7             : #include "ftl_layout.h"
       8             : #include "utils/ftl_layout_tracker_bdev.h"
       9             : #include "mngt/ftl_mngt.h"
      10             : #include "ftl_nvc_bdev_common.h"
      11             : 
      12             : static bool
      13           0 : is_bdev_compatible(struct spdk_ftl_dev *dev, struct spdk_bdev *bdev)
      14             : {
      15           0 :         if (!spdk_bdev_is_md_separate(bdev)) {
      16             :                 /* It doesn't support separate metadata buffer IO */
      17           0 :                 return false;
      18             :         }
      19             : 
      20           0 :         if (spdk_bdev_get_md_size(bdev) != sizeof(union ftl_md_vss)) {
      21             :                 /* Bdev's metadata is invalid size */
      22           0 :                 return false;
      23             :         }
      24             : 
      25           0 :         if (spdk_bdev_get_dif_type(bdev) != SPDK_DIF_DISABLE) {
      26             :                 /* Unsupported DIF type used by bdev */
      27           0 :                 return false;
      28             :         }
      29             : 
      30           0 :         if (ftl_md_xfer_blocks(dev) * spdk_bdev_get_md_size(bdev) > FTL_ZERO_BUFFER_SIZE) {
      31           0 :                 FTL_ERRLOG(dev, "Zero buffer too small for bdev %s metadata transfer\n",
      32             :                            spdk_bdev_get_name(bdev));
      33           0 :                 return false;
      34             :         }
      35             : 
      36           0 :         return true;
      37             : }
      38             : 
      39             : static void
      40           0 : write_io_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
      41             : {
      42           0 :         struct ftl_io *io = cb_arg;
      43           0 :         struct ftl_nv_cache *nv_cache = &io->dev->nv_cache;
      44             : 
      45           0 :         ftl_stats_bdev_io_completed(io->dev, FTL_STATS_TYPE_USER, bdev_io);
      46             : 
      47           0 :         spdk_bdev_free_io(bdev_io);
      48             : 
      49           0 :         ftl_mempool_put(nv_cache->md_pool, io->md);
      50             : 
      51           0 :         ftl_nv_cache_write_complete(io, success);
      52           0 : }
      53             : 
      54             : static void write_io(struct ftl_io *io);
      55             : 
      56             : static void
      57           0 : _nvc_vss_write(void *io)
      58             : {
      59           0 :         write_io(io);
      60           0 : }
      61             : 
      62             : static void
      63           0 : write_io(struct ftl_io *io)
      64             : {
      65           0 :         struct spdk_ftl_dev *dev = io->dev;
      66           0 :         struct ftl_nv_cache *nv_cache = &dev->nv_cache;
      67             :         int rc;
      68             : 
      69           0 :         io->md = ftl_mempool_get(dev->nv_cache.md_pool);
      70           0 :         if (spdk_unlikely(!io->md)) {
      71           0 :                 ftl_abort();
      72             :         }
      73             : 
      74           0 :         ftl_nv_cache_fill_md(io);
      75             : 
      76           0 :         rc = spdk_bdev_writev_blocks_with_md(nv_cache->bdev_desc, nv_cache->cache_ioch,
      77           0 :                                              io->iov, io->iov_cnt, io->md,
      78             :                                              ftl_addr_to_nvc_offset(dev, io->addr), io->num_blocks,
      79             :                                              write_io_cb, io);
      80           0 :         if (spdk_unlikely(rc)) {
      81           0 :                 if (rc == -ENOMEM) {
      82             :                         struct spdk_bdev *bdev;
      83             : 
      84           0 :                         ftl_mempool_put(nv_cache->md_pool, io->md);
      85           0 :                         io->md = NULL;
      86             : 
      87           0 :                         bdev = spdk_bdev_desc_get_bdev(nv_cache->bdev_desc);
      88           0 :                         io->bdev_io_wait.bdev = bdev;
      89           0 :                         io->bdev_io_wait.cb_fn = _nvc_vss_write;
      90           0 :                         io->bdev_io_wait.cb_arg = io;
      91           0 :                         spdk_bdev_queue_io_wait(bdev, nv_cache->cache_ioch, &io->bdev_io_wait);
      92             :                 } else {
      93           0 :                         ftl_abort();
      94             :                 }
      95             :         }
      96           0 : }
      97             : 
      98             : struct nvc_recover_open_chunk_ctx {
      99             :         struct ftl_nv_cache_chunk *chunk;
     100             :         struct ftl_rq *rq;
     101             :         uint64_t addr;
     102             :         uint64_t to_read;
     103             : };
     104             : 
     105             : static void
     106           0 : nvc_recover_open_chunk_read_vss_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
     107             : {
     108           0 :         struct ftl_mngt_process *mngt = cb_arg;
     109           0 :         struct spdk_ftl_dev *dev = ftl_mngt_get_dev(mngt);
     110           0 :         struct nvc_recover_open_chunk_ctx *ctx = ftl_mngt_get_process_ctx(mngt);
     111           0 :         struct ftl_nv_cache_chunk *chunk = ctx->chunk;
     112           0 :         struct ftl_rq *rq = ctx->rq;
     113             :         union ftl_md_vss *md;
     114           0 :         uint64_t cache_offset = bdev_io->u.bdev.offset_blocks;
     115           0 :         uint64_t blocks = bdev_io->u.bdev.num_blocks;
     116           0 :         ftl_addr addr = ftl_addr_from_nvc_offset(dev, cache_offset);
     117             : 
     118           0 :         spdk_bdev_free_io(bdev_io);
     119           0 :         if (!success) {
     120           0 :                 ftl_mngt_fail_step(mngt);
     121           0 :                 return;
     122             :         }
     123             : 
     124             :         /* Rebuild P2L map */
     125           0 :         for (rq->iter.idx = 0; rq->iter.idx < blocks; rq->iter.idx++) {
     126           0 :                 md = rq->entries[rq->iter.idx].io_md;
     127           0 :                 if (md->nv_cache.seq_id != chunk->md->seq_id) {
     128           0 :                         md->nv_cache.lba = FTL_LBA_INVALID;
     129           0 :                         md->nv_cache.seq_id = 0;
     130             :                 }
     131             : 
     132           0 :                 ftl_nv_cache_chunk_set_addr(chunk, md->nv_cache.lba, addr + rq->iter.idx);
     133             :         }
     134             : 
     135           0 :         assert(ctx->to_read >= blocks);
     136           0 :         ctx->addr += blocks;
     137           0 :         ctx->to_read -= blocks;
     138           0 :         ftl_mngt_continue_step(mngt);
     139             : 
     140             : }
     141             : 
     142             : static void
     143           0 : nvc_recover_open_chunk_read_vss(struct spdk_ftl_dev *dev,
     144             :                                 struct ftl_mngt_process *mngt)
     145             : {
     146           0 :         struct nvc_recover_open_chunk_ctx *ctx = ftl_mngt_get_process_ctx(mngt);
     147           0 :         uint64_t blocks = spdk_min(ctx->rq->num_blocks, ctx->to_read);
     148             :         int rc;
     149             : 
     150           0 :         if (blocks) {
     151           0 :                 rc = spdk_bdev_read_blocks_with_md(dev->nv_cache.bdev_desc, dev->nv_cache.cache_ioch,
     152           0 :                                                    ctx->rq->io_payload, ctx->rq->io_md, ctx->addr, blocks,
     153             :                                                    nvc_recover_open_chunk_read_vss_cb, mngt);
     154           0 :                 if (rc) {
     155           0 :                         ftl_mngt_fail_step(mngt);
     156           0 :                         return;
     157             :                 }
     158             :         } else {
     159           0 :                 ftl_mngt_next_step(mngt);
     160             :         }
     161             : }
     162             : 
     163             : static int
     164           0 : nvc_recover_open_chunk_init_handler(struct spdk_ftl_dev *dev,
     165             :                                     struct ftl_mngt_process *mngt, void *init_ctx)
     166             : {
     167           0 :         struct nvc_recover_open_chunk_ctx *ctx = ftl_mngt_get_process_ctx(mngt);
     168             : 
     169           0 :         ctx->chunk = init_ctx;
     170           0 :         ctx->rq = ftl_rq_new(dev, dev->nv_cache.md_size);
     171           0 :         if (NULL == ctx->rq) {
     172           0 :                 return -ENOMEM;
     173             :         }
     174             : 
     175           0 :         ctx->addr = ctx->chunk->offset;
     176           0 :         ctx->to_read = chunk_tail_md_offset(&dev->nv_cache);
     177             : 
     178           0 :         return 0;
     179             : }
     180             : 
     181             : static void
     182           0 : nvc_recover_open_chunk_deinit_handler(struct spdk_ftl_dev *dev,
     183             :                                       struct ftl_mngt_process *mngt)
     184             : {
     185           0 :         struct nvc_recover_open_chunk_ctx *ctx = ftl_mngt_get_process_ctx(mngt);
     186             : 
     187           0 :         ftl_rq_del(ctx->rq);
     188           0 : }
     189             : 
     190             : static const struct ftl_mngt_process_desc desc_recover_open_chunk = {
     191             :         .name = "Recover open chunk",
     192             :         .ctx_size = sizeof(struct nvc_recover_open_chunk_ctx),
     193             :         .init_handler = nvc_recover_open_chunk_init_handler,
     194             :         .deinit_handler = nvc_recover_open_chunk_deinit_handler,
     195             :         .steps = {
     196             :                 {
     197             :                         .name = "Chunk recovery, read vss",
     198             :                         .action = nvc_recover_open_chunk_read_vss
     199             :                 },
     200             :                 {}
     201             :         }
     202             : };
     203             : 
     204             : static void
     205           0 : nvc_recover_open_chunk(struct spdk_ftl_dev *dev,
     206             :                        struct ftl_mngt_process *mngt,
     207             :                        struct ftl_nv_cache_chunk *chunk)
     208             : {
     209           0 :         ftl_mngt_call_process(mngt, &desc_recover_open_chunk, chunk);
     210           0 : }
     211             : 
     212             : struct ftl_nv_cache_device_type nvc_bdev_vss = {
     213             :         .name = "bdev",
     214             :         .features = {
     215             :         },
     216             :         .ops = {
     217             :                 .is_bdev_compatible = is_bdev_compatible,
     218             :                 .is_chunk_active = ftl_nvc_bdev_common_is_chunk_active,
     219             :                 .md_layout_ops = {
     220             :                         .region_create = ftl_nvc_bdev_common_region_create,
     221             :                         .region_open = ftl_nvc_bdev_common_region_open,
     222             :                 },
     223             :                 .write = write_io,
     224             :                 .recover_open_chunk = nvc_recover_open_chunk,
     225             :         }
     226             : };
     227           0 : FTL_NV_CACHE_DEVICE_TYPE_REGISTER(nvc_bdev_vss)

Generated by: LCOV version 1.15