1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2022 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #ifndef FTL_INTERNAL_H 7 #define FTL_INTERNAL_H 8 9 #include "spdk/stdinc.h" 10 #include "spdk/crc32.h" 11 #include "spdk/util.h" 12 #include "spdk/uuid.h" 13 14 #include "utils/ftl_bitmap.h" 15 16 /* Marks address as invalid */ 17 #define FTL_ADDR_INVALID ((ftl_addr)-1) 18 /* Marks LBA as invalid */ 19 #define FTL_LBA_INVALID ((uint64_t)-1) 20 /* Smallest data unit size */ 21 #define FTL_BLOCK_SIZE 4096ULL 22 23 #define FTL_P2L_VERSION_0 0 24 #define FTL_P2L_VERSION_1 1 25 26 #define FTL_P2L_VERSION_CURRENT FTL_P2L_VERSION_1 27 28 /* 29 * This type represents address in the ftl address space. Values from 0 to based bdev size are 30 * mapped directly to base device lbas. Values above that represent nv cache lbas. 31 */ 32 typedef uint64_t ftl_addr; 33 34 struct spdk_ftl_dev; 35 36 enum ftl_md_type { 37 FTL_MD_TYPE_BAND, 38 FTL_MD_TYPE_CHUNK 39 }; 40 41 enum ftl_band_type { 42 FTL_BAND_TYPE_GC = 1, 43 FTL_BAND_TYPE_COMPACTION 44 }; 45 46 enum ftl_md_status { 47 FTL_MD_SUCCESS, 48 /* Metadata read failure */ 49 FTL_MD_IO_FAILURE, 50 /* Invalid version */ 51 FTL_MD_INVALID_VER, 52 /* UUID doesn't match */ 53 FTL_MD_NO_MD, 54 /* UUID and version matches but CRC doesn't */ 55 FTL_MD_INVALID_CRC, 56 /* Vld or p2l map size doesn't match */ 57 FTL_MD_INVALID_SIZE 58 }; 59 60 struct ftl_p2l_map_entry { 61 uint64_t lba; 62 uint64_t seq_id; 63 }; 64 65 /* Number of LBAs that could be stored in a single block */ 66 #define FTL_NUM_LBA_IN_BLOCK (FTL_BLOCK_SIZE / sizeof(struct ftl_p2l_map_entry)) 67 68 /* 69 * Mapping of physical (actual location on disk) to logical (user's POV) addresses. Used in two main scenarios: 70 * - during relocation FTL needs to pin L2P pages (this allows to check which pages to pin) and move still valid blocks 71 * (valid map allows for preliminary elimination of invalid physical blocks, but user data could invalidate a location 72 * during read/write operation, so actual comparison against L2P needs to be done) 73 * - After dirty shutdown the state of the L2P is unknown and needs to be rebuilt - it is done by applying all P2L, taking 74 * into account ordering of user writes 75 */ 76 struct ftl_p2l_map { 77 /* Number of valid LBAs */ 78 size_t num_valid; 79 80 /* P2L map's reference count, prevents premature release of resources during dirty shutdown recovery for open bands */ 81 size_t ref_cnt; 82 83 /* Bitmap of valid LBAs */ 84 struct ftl_bitmap *valid; 85 86 /* P2L map (only valid for open/relocating bands) */ 87 union { 88 struct ftl_p2l_map_entry *band_map; 89 void *chunk_map; 90 }; 91 92 /* DMA buffer for region's metadata entry */ 93 union { 94 struct ftl_band_md *band_dma_md; 95 96 struct ftl_nv_cache_chunk_md *chunk_dma_md; 97 }; 98 99 /* P2L checkpointing region */ 100 struct ftl_p2l_ckpt *p2l_ckpt; 101 }; 102 103 struct ftl_p2l_sync_ctx { 104 struct ftl_band *band; 105 uint64_t page_start; 106 uint64_t page_end; 107 int md_region; 108 }; 109 110 struct ftl_p2l_ckpt_page { 111 struct ftl_p2l_map_entry map[FTL_NUM_LBA_IN_BLOCK]; 112 }; 113 114 struct ftl_p2l_ckpt; 115 struct ftl_band; 116 struct spdk_ftl_dev; 117 struct ftl_mngt_process; 118 struct ftl_rq; 119 120 int ftl_p2l_ckpt_init(struct spdk_ftl_dev *dev); 121 122 void ftl_p2l_ckpt_deinit(struct spdk_ftl_dev *dev); 123 124 void ftl_p2l_ckpt_issue(struct ftl_rq *rq); 125 126 struct ftl_p2l_ckpt *ftl_p2l_ckpt_acquire(struct spdk_ftl_dev *dev); 127 128 struct ftl_p2l_ckpt *ftl_p2l_ckpt_acquire_region_type(struct spdk_ftl_dev *dev, 129 uint32_t region_type); 130 131 void ftl_p2l_ckpt_release(struct spdk_ftl_dev *dev, struct ftl_p2l_ckpt *ckpt); 132 133 enum ftl_layout_region_type ftl_p2l_ckpt_region_type(const struct ftl_p2l_ckpt *ckpt); 134 135 #if defined(DEBUG) 136 void ftl_p2l_validate_ckpt(struct ftl_band *band); 137 #else 138 static inline void 139 ftl_p2l_validate_ckpt(struct ftl_band *band) 140 { 141 } 142 #endif 143 144 int ftl_mngt_p2l_ckpt_get_seq_id(struct spdk_ftl_dev *dev, int md_region); 145 146 int ftl_mngt_p2l_ckpt_restore(struct ftl_band *band, uint32_t md_region, uint64_t seq_id); 147 148 int ftl_mngt_p2l_ckpt_restore_clean(struct ftl_band *band); 149 150 void ftl_mngt_p2l_ckpt_restore_shm_clean(struct ftl_band *band); 151 152 void ftl_mngt_persist_bands_p2l(struct ftl_mngt_process *mngt); 153 154 struct ftl_reloc *ftl_reloc_init(struct spdk_ftl_dev *dev); 155 156 void ftl_reloc_free(struct ftl_reloc *reloc); 157 158 void ftl_reloc(struct ftl_reloc *reloc); 159 160 void ftl_reloc_halt(struct ftl_reloc *reloc); 161 162 void ftl_reloc_resume(struct ftl_reloc *reloc); 163 164 bool ftl_reloc_is_halted(const struct ftl_reloc *reloc); 165 166 #endif /* FTL_INTERNAL_H */ 167