xref: /spdk/lib/ftl/ftl_layout.h (revision f8410506e19c71a2a8979946bd5ca0314d2146d4)
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 };
61 
62 /* last nvc/base region in terms of lba address space */
63 #define FTL_LAYOUT_REGION_LAST_NVC FTL_LAYOUT_REGION_TYPE_DATA_NVC
64 #define FTL_LAYOUT_REGION_LAST_BASE FTL_LAYOUT_REGION_TYPE_VALID_MAP
65 #define FTL_LAYOUT_REGION_TYPE_FREE_BASE (UINT32_MAX - 2)
66 #define FTL_LAYOUT_REGION_TYPE_FREE_NVC (UINT32_MAX - 1)
67 #define FTL_LAYOUT_REGION_TYPE_INVALID (UINT32_MAX)
68 
69 struct ftl_layout_region_descriptor {
70 	/* Current version of the region */
71 	uint64_t version;
72 
73 	/* Offset in FTL_BLOCK_SIZE unit where the region exists on the device */
74 	uint64_t offset;
75 
76 	/* Number of blocks in FTL_BLOCK_SIZE unit */
77 	uint64_t blocks;
78 
79 	struct ftl_superblock_md_region *sb_md_reg;
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 	/* Latest region version */
94 	struct ftl_layout_region_descriptor current;
95 
96 	/* Previous region version, if found */
97 	struct ftl_layout_region_descriptor prev;
98 
99 	/* Number of blocks in FTL_BLOCK_SIZE unit of a single entry.
100 	 * A metadata region may be subdivided into multiple smaller entries.
101 	 * Eg. there's one region describing all bands, but you may be able to access
102 	 * metadata of a single one.
103 	 */
104 	uint64_t entry_size;
105 
106 	/* Number of entries */
107 	uint64_t num_entries;
108 
109 	/* VSS MD size or 0:disable VSS MD */
110 	uint64_t vss_blksz;
111 
112 	/* Device of region */
113 	struct spdk_bdev_desc *bdev_desc;
114 
115 	/* IO channel of region */
116 	struct spdk_io_channel *ioch;
117 };
118 
119 /*
120  * This structure describes the geometry (space organization) of FTL
121  */
122 struct ftl_layout {
123 	/* Organization for base device */
124 	struct {
125 		uint64_t total_blocks;
126 		uint64_t num_usable_blocks;
127 		uint64_t user_blocks;
128 	} base;
129 
130 	/* Organization for NV cache */
131 	struct {
132 		uint64_t total_blocks;
133 		uint64_t chunk_data_blocks;
134 		uint64_t chunk_meta_size;
135 		uint64_t chunk_count;
136 		uint64_t chunk_tail_md_num_blocks;
137 	} nvc;
138 
139 	/* Information corresponding to L2P */
140 	struct {
141 		/* Address length in bits */
142 		uint64_t addr_length;
143 		/* Address size in bytes */
144 		uint64_t addr_size;
145 		/* Number of LBAS in memory page */
146 		uint64_t lbas_in_page;
147 	} l2p;
148 
149 	/* Organization of P2L checkpoints */
150 	struct {
151 		/* Number of P2L checkpoint pages */
152 		uint64_t ckpt_pages;
153 	} p2l;
154 
155 	struct ftl_layout_region region[FTL_LAYOUT_REGION_TYPE_MAX];
156 
157 	/* Metadata object corresponding to the regions */
158 	struct ftl_md *md[FTL_LAYOUT_REGION_TYPE_MAX];
159 };
160 
161 /**
162  * @brief FTL MD layout operations interface
163  */
164 struct ftl_md_layout_ops {
165 	/**
166 	 * @brief Create a new MD region
167 	 *
168 	 * @param dev ftl device
169 	 * @param reg_type region type
170 	 * @param reg_version region version
171 	 * @param entry_size MD entry size in bytes
172 	 * @param entry_count number of MD entries
173 	 *
174 	 * @return pointer to FTL MD region descriptor or NULL if failed
175 	 */
176 	struct ftl_layout_region *(*region_create)(struct spdk_ftl_dev *dev,
177 			enum ftl_layout_region_type reg_type, uint32_t reg_version, size_t entry_size, size_t entry_count);
178 };
179 
180 /**
181  * @brief Get number of blocks required to store an MD region
182  *
183  * @param dev ftl device
184  * @param bytes size of the MD region in bytes
185  *
186  * @retval Number of blocks required to store an MD region
187  */
188 uint64_t ftl_md_region_blocks(struct spdk_ftl_dev *dev, uint64_t bytes);
189 
190 /**
191  * @brief Get name of an MD region
192  *
193  * @param reg_type MD region type
194  *
195  * @return Name of the MD region specified
196  */
197 const char *ftl_md_region_name(enum ftl_layout_region_type reg_type);
198 
199 /**
200  * @brief Setup FTL layout
201  */
202 int ftl_layout_setup(struct spdk_ftl_dev *dev);
203 
204 /**
205  * @brief Setup FTL layout of a superblock
206  */
207 int ftl_layout_setup_superblock(struct spdk_ftl_dev *dev);
208 
209 void ftl_layout_dump(struct spdk_ftl_dev *dev);
210 int ftl_validate_regions(struct spdk_ftl_dev *dev, struct ftl_layout *layout);
211 
212 /**
213  * @brief Get number of blocks required to store metadata on bottom device
214  */
215 uint64_t ftl_layout_base_md_blocks(struct spdk_ftl_dev *dev);
216 
217 #endif /* FTL_LAYOUT_H */
218