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