1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2023 Solidigm All Rights Reserved 3 * Copyright (C) 2022 Intel Corporation. 4 * All rights reserved. 5 */ 6 7 #ifndef FTL_LAYOUT_H 8 #define FTL_LAYOUT_H 9 10 #include "spdk/stdinc.h" 11 12 struct spdk_ftl_dev; 13 struct ftl_md; 14 15 #define FTL_LAYOUT_REGION_TYPE_P2L_COUNT \ 16 (FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX - FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN + 1) 17 18 enum ftl_layout_region_type { 19 /* Superblock describing the basic FTL information */ 20 FTL_LAYOUT_REGION_TYPE_SB = 0, 21 /* Mirrored instance of the superblock on the base device */ 22 FTL_LAYOUT_REGION_TYPE_SB_BASE = 1, 23 /* If using cached L2P, this region stores the serialized instance of it */ 24 FTL_LAYOUT_REGION_TYPE_L2P = 2, 25 26 /* State of bands */ 27 FTL_LAYOUT_REGION_TYPE_BAND_MD = 3, 28 /* Mirrored instance of bands state */ 29 FTL_LAYOUT_REGION_TYPE_BAND_MD_MIRROR = 4, 30 31 /* Map of valid physical addresses, used for more efficient garbage collection */ 32 FTL_LAYOUT_REGION_TYPE_VALID_MAP = 5, 33 34 /* State of chunks */ 35 FTL_LAYOUT_REGION_TYPE_NVC_MD = 6, 36 /* Mirrored instance of the state of chunks */ 37 FTL_LAYOUT_REGION_TYPE_NVC_MD_MIRROR = 7, 38 39 /* User data region on the nv cache device */ 40 FTL_LAYOUT_REGION_TYPE_DATA_NVC = 8, 41 42 /* User data region on the base device */ 43 FTL_LAYOUT_REGION_TYPE_DATA_BASE = 9, 44 45 /* P2L checkpointing allows for emulation of VSS on base device. 46 * 4 entries are needed - 2 for each writer */ 47 FTL_LAYOUT_REGION_TYPE_P2L_CKPT_GC = 10, 48 FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MIN = FTL_LAYOUT_REGION_TYPE_P2L_CKPT_GC, 49 FTL_LAYOUT_REGION_TYPE_P2L_CKPT_GC_NEXT = 11, 50 FTL_LAYOUT_REGION_TYPE_P2L_CKPT_COMP = 12, 51 FTL_LAYOUT_REGION_TYPE_P2L_CKPT_COMP_NEXT = 13, 52 FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX = FTL_LAYOUT_REGION_TYPE_P2L_CKPT_COMP_NEXT, 53 54 /* Information about trimmed space in FTL */ 55 FTL_LAYOUT_REGION_TYPE_TRIM_MD = 14, 56 /* Mirrored information about trim */ 57 FTL_LAYOUT_REGION_TYPE_TRIM_MD_MIRROR = 15, 58 59 FTL_LAYOUT_REGION_TYPE_MAX = 16, 60 FTL_LAYOUT_REGION_TYPE_MAX_V3 = 16 61 }; 62 63 /* last nvc/base region in terms of lba address space */ 64 #define FTL_LAYOUT_REGION_LAST_NVC FTL_LAYOUT_REGION_TYPE_DATA_NVC 65 #define FTL_LAYOUT_REGION_LAST_BASE FTL_LAYOUT_REGION_TYPE_VALID_MAP 66 #define FTL_LAYOUT_REGION_TYPE_FREE_BASE (UINT32_MAX - 2) 67 #define FTL_LAYOUT_REGION_TYPE_FREE_NVC (UINT32_MAX - 1) 68 #define FTL_LAYOUT_REGION_TYPE_FREE (UINT32_MAX - 1) 69 #define FTL_LAYOUT_REGION_TYPE_INVALID (UINT32_MAX) 70 71 struct ftl_layout_region_descriptor { 72 /* Current version of the region */ 73 uint64_t version; 74 75 /* Offset in FTL_BLOCK_SIZE unit where the region exists on the device */ 76 uint64_t offset; 77 78 /* Number of blocks in FTL_BLOCK_SIZE unit */ 79 uint64_t blocks; 80 }; 81 82 /* Data or metadata region on devices */ 83 struct ftl_layout_region { 84 /* Name of the region */ 85 const char *name; 86 87 /* Region type */ 88 enum ftl_layout_region_type type; 89 90 /* Mirror region type - a region may be mirrored for higher durability */ 91 enum ftl_layout_region_type mirror_type; 92 93 /* Current region version */ 94 struct ftl_layout_region_descriptor current; 95 96 /* Number of blocks in FTL_BLOCK_SIZE unit of a single entry. 97 * A metadata region may be subdivided into multiple smaller entries. 98 * Eg. there's one region describing all bands, but you may be able to access 99 * metadata of a single one. 100 */ 101 uint64_t entry_size; 102 103 /* Number of entries */ 104 uint64_t num_entries; 105 106 /* VSS MD size or 0:disable VSS MD */ 107 uint64_t vss_blksz; 108 109 /* Device of region */ 110 struct spdk_bdev_desc *bdev_desc; 111 112 /* IO channel of region */ 113 struct spdk_io_channel *ioch; 114 }; 115 116 /* 117 * This structure describes the geometry (space organization) of FTL 118 */ 119 struct ftl_layout { 120 /* Organization for base device */ 121 struct { 122 uint64_t total_blocks; 123 uint64_t num_usable_blocks; 124 uint64_t user_blocks; 125 } base; 126 127 /* Organization for NV cache */ 128 struct { 129 uint64_t total_blocks; 130 uint64_t chunk_data_blocks; 131 uint64_t chunk_count; 132 uint64_t chunk_tail_md_num_blocks; 133 } nvc; 134 135 /* Information corresponding to L2P */ 136 struct { 137 /* Address length in bits */ 138 uint64_t addr_length; 139 /* Address size in bytes */ 140 uint64_t addr_size; 141 /* Number of LBAS in memory page */ 142 uint64_t lbas_in_page; 143 } l2p; 144 145 /* Organization of P2L checkpoints */ 146 struct { 147 /* Number of P2L checkpoint pages */ 148 uint64_t ckpt_pages; 149 /* Number of P2L checkpoint pages to be written per write unit size */ 150 uint64_t pages_per_xfer; 151 } p2l; 152 153 struct ftl_layout_region region[FTL_LAYOUT_REGION_TYPE_MAX]; 154 155 /* Metadata object corresponding to the regions */ 156 struct ftl_md *md[FTL_LAYOUT_REGION_TYPE_MAX]; 157 }; 158 159 /** 160 * @brief FTL MD layout operations interface 161 */ 162 struct ftl_md_layout_ops { 163 /** 164 * @brief Create a new MD region 165 * 166 * @param dev ftl device 167 * @param reg_type region type 168 * @param reg_version region version 169 * @param entry_size MD entry size in bytes 170 * @param entry_count number of MD entries 171 * 172 * @retval 0 on success 173 * @retval -1 on fault 174 */ 175 int (*region_create)(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, 176 uint32_t reg_version, size_t reg_blks); 177 178 int (*region_open)(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type, 179 uint32_t reg_version, size_t entry_size, size_t entry_count, struct ftl_layout_region *region); 180 }; 181 182 /** 183 * @brief Get number of blocks required to store an MD region 184 * 185 * @param dev ftl device 186 * @param bytes size of the MD region in bytes 187 * 188 * @retval Number of blocks required to store an MD region 189 */ 190 uint64_t ftl_md_region_blocks(struct spdk_ftl_dev *dev, uint64_t bytes); 191 192 /** 193 * @brief Get number of blocks for md_region aligned to a common value 194 * 195 * @param dev ftl device 196 * @param blocks size of the MD region in blocks 197 * 198 * @retval Aligned number of blocks required to store an MD region 199 */ 200 uint64_t ftl_md_region_align_blocks(struct spdk_ftl_dev *dev, uint64_t blocks); 201 202 /** 203 * @brief Get name of an MD region 204 * 205 * @param reg_type MD region type 206 * 207 * @return Name of the MD region specified 208 */ 209 const char *ftl_md_region_name(enum ftl_layout_region_type reg_type); 210 211 /** 212 * @brief Setup FTL layout 213 */ 214 int ftl_layout_setup(struct spdk_ftl_dev *dev); 215 216 /** 217 * @brief Setup FTL layout of a superblock 218 */ 219 int ftl_layout_setup_superblock(struct spdk_ftl_dev *dev); 220 221 /** 222 * @brief Clear the superblock from the layout. Used after failure of shared memory files verification causes a retry. 223 */ 224 int ftl_layout_clear_superblock(struct spdk_ftl_dev *dev); 225 226 void ftl_layout_dump(struct spdk_ftl_dev *dev); 227 int ftl_validate_regions(struct spdk_ftl_dev *dev, struct ftl_layout *layout); 228 229 /** 230 * @brief Get number of blocks required to store metadata on bottom device 231 */ 232 uint64_t ftl_layout_base_md_blocks(struct spdk_ftl_dev *dev); 233 234 /** 235 * @brief Get the FTL layout region 236 * 237 * @param dev FTL device 238 * @param reg_type type of the layout region 239 * 240 * @return pointer to the layout region if region was created or NULL, if not created 241 */ 242 struct ftl_layout_region *ftl_layout_region_get(struct spdk_ftl_dev *dev, 243 enum ftl_layout_region_type reg_type); 244 245 /** 246 * @brief Store the layout data in the blob 247 * 248 * @param dev FTL device 249 * @param blob_buf Blob buffer where the layout will be stored 250 * @param blob_buf_sz Size of the blob buffer in bytes 251 * 252 * @return Number of bytes the stored blob entries take up. 0 if calculated value would exceed blob_buf_sz. 253 */ 254 size_t ftl_layout_blob_store(struct spdk_ftl_dev *dev, void *blob_buf, size_t blob_buf_sz); 255 256 /** 257 * @brief Load the layout data from the blob 258 * 259 * @param dev FTL device 260 * @param blob_buf Blob buffer from which the layout will be loaded 261 * @param blob_sz Size of the blob buffer in bytes 262 * 263 * @return 0 on success, -1 on failure 264 */ 265 int ftl_layout_blob_load(struct spdk_ftl_dev *dev, void *blob_buf, size_t blob_sz); 266 267 uint64_t ftl_layout_base_offset(struct spdk_ftl_dev *dev); 268 269 #endif /* FTL_LAYOUT_H */ 270