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