xref: /spdk/lib/ftl/ftl_layout.h (revision 42fd001310188f0635a3953f3b0ea0b33a840902)
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_NV_CACHE_CHUNK_DATA_SIZE(blocks) ((uint64_t)blocks * FTL_BLOCK_SIZE)
16 #define FTL_NV_CACHE_CHUNK_SIZE(blocks) \
17 	(FTL_NV_CACHE_CHUNK_DATA_SIZE(blocks) + (2 * FTL_NV_CACHE_CHUNK_MD_SIZE))
18 
19 #define FTL_LAYOUT_REGION_TYPE_P2L_COUNT \
20 	(FTL_LAYOUT_REGION_TYPE_P2L_CKPT_MAX - FTL_LAYOUT_REGION_TYPE_P2L_CKPT_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 	FTL_LAYOUT_REGION_TYPE_MAX = 16,
64 	FTL_LAYOUT_REGION_TYPE_MAX_V3 = 16
65 };
66 
67 /* last nvc/base region in terms of lba address space */
68 #define FTL_LAYOUT_REGION_LAST_NVC FTL_LAYOUT_REGION_TYPE_DATA_NVC
69 #define FTL_LAYOUT_REGION_LAST_BASE FTL_LAYOUT_REGION_TYPE_VALID_MAP
70 #define FTL_LAYOUT_REGION_TYPE_FREE_BASE (UINT32_MAX - 2)
71 #define FTL_LAYOUT_REGION_TYPE_FREE_NVC (UINT32_MAX - 1)
72 #define FTL_LAYOUT_REGION_TYPE_FREE (UINT32_MAX - 1)
73 #define FTL_LAYOUT_REGION_TYPE_INVALID (UINT32_MAX)
74 
75 struct ftl_layout_region_descriptor {
76 	/* Current version of the region */
77 	uint64_t version;
78 
79 	/* Offset in FTL_BLOCK_SIZE unit where the region exists on the device */
80 	uint64_t offset;
81 
82 	/* Number of blocks in FTL_BLOCK_SIZE unit */
83 	uint64_t blocks;
84 };
85 
86 /* Data or metadata region on devices */
87 struct ftl_layout_region {
88 	/* Name of the region */
89 	const char *name;
90 
91 	/* Region type */
92 	enum ftl_layout_region_type type;
93 
94 	/* Mirror region type - a region may be mirrored for higher durability */
95 	enum ftl_layout_region_type mirror_type;
96 
97 	/* Current region version */
98 	struct ftl_layout_region_descriptor current;
99 
100 	/* Number of blocks in FTL_BLOCK_SIZE unit of a single entry.
101 	 * A metadata region may be subdivided into multiple smaller entries.
102 	 * Eg. there's one region describing all bands, but you may be able to access
103 	 * metadata of a single one.
104 	 */
105 	uint64_t entry_size;
106 
107 	/* Number of entries */
108 	uint64_t num_entries;
109 
110 	/* VSS MD size or 0:disable VSS MD */
111 	uint64_t vss_blksz;
112 
113 	/* Device of region */
114 	struct spdk_bdev_desc *bdev_desc;
115 
116 	/* IO channel of region */
117 	struct spdk_io_channel *ioch;
118 };
119 
120 /*
121  * This structure describes the geometry (space organization) of FTL
122  */
123 struct ftl_layout {
124 	/* Organization for base device */
125 	struct {
126 		uint64_t total_blocks;
127 		uint64_t num_usable_blocks;
128 		uint64_t user_blocks;
129 	} base;
130 
131 	/* Organization for NV cache */
132 	struct {
133 		uint64_t total_blocks;
134 		uint64_t chunk_data_blocks;
135 		uint64_t chunk_meta_size;
136 		uint64_t chunk_count;
137 		uint64_t chunk_tail_md_num_blocks;
138 	} nvc;
139 
140 	/* Information corresponding to L2P */
141 	struct {
142 		/* Address length in bits */
143 		uint64_t addr_length;
144 		/* Address size in bytes */
145 		uint64_t addr_size;
146 		/* Number of LBAS in memory page */
147 		uint64_t lbas_in_page;
148 	} l2p;
149 
150 	/* Organization of P2L checkpoints */
151 	struct {
152 		/* Number of P2L checkpoint pages */
153 		uint64_t ckpt_pages;
154 	} p2l;
155 
156 	struct ftl_layout_region region[FTL_LAYOUT_REGION_TYPE_MAX];
157 
158 	/* Metadata object corresponding to the regions */
159 	struct ftl_md *md[FTL_LAYOUT_REGION_TYPE_MAX];
160 };
161 
162 /**
163  * @brief FTL MD layout operations interface
164  */
165 struct ftl_md_layout_ops {
166 	/**
167 	 * @brief Create a new MD region
168 	 *
169 	 * @param dev ftl device
170 	 * @param reg_type region type
171 	 * @param reg_version region version
172 	 * @param entry_size MD entry size in bytes
173 	 * @param entry_count number of MD entries
174 	 *
175 	 * @retval 0 on success
176 	 * @retval -1 on fault
177 	 */
178 	int (*region_create)(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type,
179 			     uint32_t reg_version, size_t reg_blks);
180 
181 	int (*region_open)(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type,
182 			   uint32_t reg_version, size_t entry_size, size_t entry_count, struct ftl_layout_region *region);
183 };
184 
185 /**
186  * @brief Get number of blocks required to store an MD region
187  *
188  * @param dev ftl device
189  * @param bytes size of the MD region in bytes
190  *
191  * @retval Number of blocks required to store an MD region
192  */
193 uint64_t ftl_md_region_blocks(struct spdk_ftl_dev *dev, uint64_t bytes);
194 
195 /**
196  * @brief Get number of blocks for md_region aligned to a common value
197  *
198  * @param dev ftl device
199  * @param blocks size of the MD region in blocks
200  *
201  * @retval Aligned number of blocks required to store an MD region
202  */
203 uint64_t ftl_md_region_align_blocks(struct spdk_ftl_dev *dev, uint64_t blocks);
204 
205 /**
206  * @brief Get name of an MD region
207  *
208  * @param reg_type MD region type
209  *
210  * @return Name of the MD region specified
211  */
212 const char *ftl_md_region_name(enum ftl_layout_region_type reg_type);
213 
214 /**
215  * @brief Setup FTL layout
216  */
217 int ftl_layout_setup(struct spdk_ftl_dev *dev);
218 
219 /**
220  * @brief Setup FTL layout of a superblock
221  */
222 int ftl_layout_setup_superblock(struct spdk_ftl_dev *dev);
223 
224 /**
225  * @brief Clear the superblock from the layout. Used after failure of shared memory files verification causes a retry.
226  */
227 int ftl_layout_clear_superblock(struct spdk_ftl_dev *dev);
228 
229 void ftl_layout_dump(struct spdk_ftl_dev *dev);
230 int ftl_validate_regions(struct spdk_ftl_dev *dev, struct ftl_layout *layout);
231 
232 /**
233  * @brief Get number of blocks required to store metadata on bottom device
234  */
235 uint64_t ftl_layout_base_md_blocks(struct spdk_ftl_dev *dev);
236 
237 /**
238  * @brief Get the FTL layout region
239  *
240  * @param dev FTL device
241  * @param reg_type type of the layout region
242  *
243  * @return pointer to the layout region if region was created or NULL, if not created
244  */
245 struct ftl_layout_region *ftl_layout_region_get(struct spdk_ftl_dev *dev,
246 		enum ftl_layout_region_type reg_type);
247 
248 /**
249  * @brief Store the layout data in the blob
250  *
251  * @param dev FTL device
252  * @param blob_buf Blob buffer where the layout will be stored
253  * @param blob_buf_sz Size of the blob buffer in bytes
254  *
255  * @return Number of bytes the stored blob entries take up. 0 if calculated value would exceed blob_buf_sz.
256  */
257 size_t ftl_layout_blob_store(struct spdk_ftl_dev *dev, void *blob_buf, size_t blob_buf_sz);
258 
259 /**
260  * @brief Load the layout data from the blob
261  *
262  * @param dev FTL device
263  * @param blob_buf Blob buffer from which the layout will be loaded
264  * @param blob_sz Size of the blob buffer in bytes
265  *
266  * @return 0 on success, -1 on failure
267  */
268 int ftl_layout_blob_load(struct spdk_ftl_dev *dev, void *blob_buf, size_t blob_sz);
269 
270 uint64_t ftl_layout_base_offset(struct spdk_ftl_dev *dev);
271 
272 #endif /* FTL_LAYOUT_H */
273