xref: /spdk/include/spdk/ftl.h (revision 2c01ded3719229bbdc5fd0fe93fe858b36cba96b)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2018 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #ifndef SPDK_FTL_H
7 #define SPDK_FTL_H
8 
9 #include "spdk/stdinc.h"
10 #include "spdk/uuid.h"
11 #include "spdk/thread.h"
12 #include "spdk/bdev.h"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 struct spdk_ftl_dev;
19 struct ftl_io;
20 struct spdk_jsonrpc_request;
21 
22 /* Limit thresholds */
23 enum {
24 	SPDK_FTL_LIMIT_CRIT,
25 	SPDK_FTL_LIMIT_HIGH,
26 	SPDK_FTL_LIMIT_LOW,
27 	SPDK_FTL_LIMIT_START,
28 	SPDK_FTL_LIMIT_MAX
29 };
30 
31 struct ftl_stats_error {
32 	uint64_t media;
33 	uint64_t crc;
34 	uint64_t other;
35 };
36 
37 struct ftl_stats_group {
38 	uint64_t ios;
39 	uint64_t blocks;
40 	struct ftl_stats_error errors;
41 };
42 
43 struct ftl_stats_entry {
44 	struct ftl_stats_group read;
45 	struct ftl_stats_group write;
46 };
47 
48 enum ftl_stats_type {
49 	FTL_STATS_TYPE_USER = 0,
50 	FTL_STATS_TYPE_CMP,
51 	FTL_STATS_TYPE_GC,
52 	FTL_STATS_TYPE_MD_BASE,
53 	FTL_STATS_TYPE_MD_NV_CACHE,
54 	FTL_STATS_TYPE_L2P,
55 	FTL_STATS_TYPE_MAX,
56 };
57 
58 struct ftl_stats {
59 	/* Number of times write limits were triggered by FTL writers
60 	 * (gc and compaction) dependent on number of free bands. GC starts at
61 	 * SPDK_FTL_LIMIT_START level, while at SPDK_FTL_LIMIT_CRIT compaction stops
62 	 * and only GC is allowed to work.
63 	 */
64 	uint64_t		limits[SPDK_FTL_LIMIT_MAX];
65 
66 	/* Total number of blocks with IO to the underlying devices
67 	 * 1. nv cache read/write
68 	 * 2. base bdev read/write
69 	 */
70 	uint64_t		io_activity_total;
71 
72 	struct ftl_stats_entry	entries[FTL_STATS_TYPE_MAX];
73 };
74 
75 typedef void (*spdk_ftl_stats_fn)(struct ftl_stats *stats, void *cb_arg);
76 
77 /*
78  * FTL configuration.
79  *
80  * NOTE: Do not change the layout of this structure. Only add new fields at the end.
81  */
82 struct spdk_ftl_conf {
83 	/* Device's name */
84 	char					*name;
85 
86 	/* Device UUID (valid when restoring device from disk) */
87 	struct spdk_uuid			uuid;
88 
89 	/* Percentage of base device blocks not exposed to the user */
90 	uint64_t				overprovisioning;
91 
92 	/* l2p cache size that could reside in DRAM (in MiB) */
93 	size_t					l2p_dram_limit;
94 
95 	/* Core mask - core thread plus additional relocation threads */
96 	char					*core_mask;
97 
98 	/* IO pool size per user thread */
99 	size_t					user_io_pool_size;
100 
101 	/* User writes limits */
102 	size_t					limits[SPDK_FTL_LIMIT_MAX];
103 
104 	/* FTL startup mode mask, see spdk_ftl_mode enum for possible values */
105 	uint32_t				mode;
106 
107 	struct {
108 		/* Start compaction when full chunks exceed given % of entire chunks */
109 		uint32_t			chunk_compaction_threshold;
110 
111 		/* Percentage of chunks to maintain free */
112 		uint32_t			chunk_free_target;
113 	} nv_cache;
114 
115 	/* Hole at bytes 0x60 - 0x67. */
116 	uint8_t					reserved[4];
117 
118 	/* Name of base block device (zoned or non-zoned) */
119 	char					*base_bdev;
120 
121 	/* Name of cache block device (must support extended metadata) */
122 	char					*cache_bdev;
123 
124 	/* Enable fast shutdown path */
125 	bool					fast_shutdown;
126 
127 	/* Hole at bytes 0x79 - 0x7f. */
128 	uint8_t					reserved2[7];
129 
130 	/*
131 	 * The size of spdk_ftl_conf according to the caller of this library is used for ABI
132 	 * compatibility. The library uses this field to know how many fields in this
133 	 * structure are valid. And the library will populate any remaining fields with default values.
134 	 */
135 	size_t					conf_size;
136 } __attribute__((packed));
137 SPDK_STATIC_ASSERT(sizeof(struct spdk_ftl_conf) == 136, "Incorrect size");
138 
139 enum spdk_ftl_mode {
140 	/* Create new device */
141 	SPDK_FTL_MODE_CREATE = (1 << 0),
142 };
143 
144 /*
145  * FTL device attributes.
146  *
147  * NOTE: Do not change the layout of this structure. Only add new fields at the end.
148  */
149 struct spdk_ftl_attrs {
150 	/* Number of logical blocks */
151 	uint64_t			num_blocks;
152 	/* Logical block size */
153 	uint64_t			block_size;
154 	/* Optimal IO size - bdev layer will split requests over this size */
155 	uint64_t			optimum_io_size;
156 };
157 
158 typedef void (*spdk_ftl_fn)(void *cb_arg, int status);
159 typedef void (*spdk_ftl_init_fn)(struct spdk_ftl_dev *dev, void *cb_arg, int status);
160 
161 /**
162  * Initializes the FTL library.
163  *
164  * @return 0 on success, negative errno otherwise.
165  */
166 int spdk_ftl_init(void);
167 
168 /**
169  * Deinitializes the FTL library.
170  */
171 void spdk_ftl_fini(void);
172 
173 /**
174  * Initialize the FTL on the given pair of bdevs - base and cache bdev.
175  * Upon receiving a successful completion callback user is free to use I/O calls.
176  *
177  * \param conf configuration for new device
178  * \param cb callback function to call when the device is created
179  * \param cb_arg callback's argument
180  *
181  * \return 0 if initialization was started successfully, negative errno otherwise.
182  */
183 int spdk_ftl_dev_init(const struct spdk_ftl_conf *conf, spdk_ftl_init_fn cb, void *cb_arg);
184 
185 /**
186  * Deinitialize and free given device.
187  *
188  * \param dev device
189  * \param cb callback function to call when the device is freed
190  * \param cb_arg callback's argument
191  *
192  * \return 0 if deinitialization was started successfully, negative errno otherwise.
193  */
194 int spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_fn cb, void *cb_arg);
195 
196 /**
197  * Retrieve device’s attributes.
198  *
199  * \param dev device
200  * \param attr Attribute structure to fill
201  * \param attrs_size Must be set to sizeof(struct spdk_ftl_attrs)
202  */
203 void spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *attr,
204 			    size_t attrs_size);
205 
206 /**
207  * Retrieve device’s configuration.
208  *
209  * \param dev device
210  * \param conf FTL configuration structure to fill
211  * \param conf_size Must be set to sizeof(struct spdk_ftl_conf)
212  */
213 void spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf,
214 			   size_t conf_size);
215 
216 /**
217  * Obtain an I/O channel for the device.
218  *
219  * \param dev device
220  *
221  * \return A handle to the I/O channel or NULL on failure.
222  */
223 struct spdk_io_channel *spdk_ftl_get_io_channel(struct spdk_ftl_dev *dev);
224 
225 /**
226  * Make a deep copy of an FTL configuration structure
227  *
228  * \param dst The destination FTL configuration
229  * \param src The source FTL configuration
230  */
231 int spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src);
232 
233 /**
234  * Release the FTL configuration resources. This does not free the structure itself.
235  *
236  * \param conf FTL configuration to deinitialize
237  */
238 void spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf);
239 
240 /**
241  * Initialize FTL configuration structure with default values.
242  *
243  * \param conf FTL configuration to initialize
244  * \param conf_size Must be set to sizeof(struct spdk_ftl_conf)
245  */
246 void spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf, size_t conf_size);
247 
248 /**
249  * Submits a read to the specified device.
250  *
251  * \param dev Device
252  * \param io Allocated ftl_io
253  * \param ch I/O channel
254  * \param lba Starting LBA to read the data
255  * \param lba_cnt Number of sectors to read
256  * \param iov Single IO vector or pointer to IO vector table
257  * \param iov_cnt Number of IO vectors
258  * \param cb_fn Callback function to invoke when the I/O is completed
259  * \param cb_arg Argument to pass to the callback function
260  *
261  * \return 0 if successfully submitted, negative errno otherwise.
262  */
263 int spdk_ftl_readv(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch,
264 		   uint64_t lba, uint64_t lba_cnt,
265 		   struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg);
266 
267 /**
268  * Submits a write to the specified device.
269  *
270  * \param dev Device
271  * \param io Allocated ftl_io
272  * \param ch I/O channel
273  * \param lba Starting LBA to write the data
274  * \param lba_cnt Number of sectors to write
275  * \param iov Single IO vector or pointer to IO vector table
276  * \param iov_cnt Number of IO vectors
277  * \param cb_fn Callback function to invoke when the I/O is completed
278  * \param cb_arg Argument to pass to the callback function
279  *
280  * \return 0 if successfully submitted, negative errno otherwise.
281  */
282 int spdk_ftl_writev(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch,
283 		    uint64_t lba, uint64_t lba_cnt,
284 		    struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg);
285 
286 /**
287  * Submits a unmap to the specified device.
288  *
289  * \param dev Device
290  * \param io Allocated ftl_io
291  * \param ch I/O channel
292  * \param lba Starting LBA to write the data
293  * \param lba_cnt Number of blocks to unmap
294  * \param cb_fn Callback function to invoke when the I/O is completed
295  * \param cb_arg Argument to pass to the callback function
296  *
297  * \return 0 if successfully submitted, negative errno otherwise.
298  */
299 int spdk_ftl_unmap(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch,
300 		   uint64_t lba, uint64_t lba_cnt, spdk_ftl_fn cb_fn, void *cb_arg);
301 
302 /**
303  * Returns the size of ftl_io struct that needs to be passed to spdk_ftl_read/write
304  *
305  * \return The size of struct
306  */
307 size_t spdk_ftl_io_size(void);
308 
309 /**
310  * Enable fast shutdown.
311  *
312  * During fast shutdown FTL will keep the necessary metadata in shared memory instead
313  * of serializing it to storage. This allows for shorter downtime during upgrade process.
314  */
315 void spdk_ftl_dev_set_fast_shutdown(struct spdk_ftl_dev *dev, bool fast_shutdown);
316 
317 /*
318  * Returns current FTL I/O statistics.
319  *
320  * \param dev Device
321  * \param stats Allocated ftl_stats
322  * \param cb_fn Callback function to invoke when the call is completed
323  * \param cb_arg Argument to pass to the callback function
324  *
325  * \return 0 if successfully submitted, negative errno otherwise.
326  */
327 int spdk_ftl_get_stats(struct spdk_ftl_dev *dev, struct ftl_stats *stats, spdk_ftl_stats_fn cb_fn,
328 		       void *cb_arg);
329 
330 /**
331  * Gets properties of the specified device.
332  *
333  * \param dev FTL device
334  * \param request JSON RPC request where the properties will be stored
335  * \param cb_fn Callback function to invoke when the operation is completed
336  * \param cb_arg Argument to pass to the callback function
337  *
338  * \return 0 if successfully submitted, negative errno otherwise.
339  */
340 int spdk_ftl_get_properties(struct spdk_ftl_dev *dev, struct spdk_jsonrpc_request *request,
341 			    spdk_ftl_fn cb_fn, void *cb_arg);
342 
343 #ifdef __cplusplus
344 }
345 #endif
346 
347 #endif /* SPDK_FTL_H */
348