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