xref: /spdk/lib/ftl/ftl_layout.h (revision 8afdeef3becfe9409cc9e7372bd0bc10e8b7d46d)
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