xref: /spdk/include/spdk/ftl.h (revision c6c1234de9e0015e670dd0b51bf6ce39ee0e07bd)
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 	/*
116 	 * This flags indicates that FTL during shutdown should execute all
117 	 * actions which are needed for upgrade to a new version
118 	 */
119 	bool					prep_upgrade_on_shutdown;
120 
121 	/* In verbose mode, user is able to get access to additional advanced FTL properties.
122 	 *
123 	 * Advanced properties currently include entries, which will result in printing large amount of data
124 	 * (e.g. state of all bands, or chunks); or allow for receiving internal state of FTL (e.g. bands currently
125 	 * used for garbage collection) - live data which may be useful for profiling, or debugging.
126 	 */
127 	bool					verbose_mode;
128 
129 	/* Hole at bytes 0x66 - 0x67. */
130 	uint8_t					reserved[2];
131 
132 	/* Name of base block device (zoned or non-zoned) */
133 	char					*base_bdev;
134 
135 	/* Name of cache block device (must support extended metadata) */
136 	char					*cache_bdev;
137 
138 	/* Enable fast shutdown path */
139 	bool					fast_shutdown;
140 
141 	/* Hole at bytes 0x79 - 0x7f. */
142 	uint8_t					reserved2[7];
143 
144 	/*
145 	 * The size of spdk_ftl_conf according to the caller of this library is used for ABI
146 	 * compatibility. The library uses this field to know how many fields in this
147 	 * structure are valid. And the library will populate any remaining fields with default values.
148 	 */
149 	size_t					conf_size;
150 } __attribute__((packed));
151 SPDK_STATIC_ASSERT(sizeof(struct spdk_ftl_conf) == 136, "Incorrect size");
152 
153 enum spdk_ftl_mode {
154 	/* Create new device */
155 	SPDK_FTL_MODE_CREATE = (1 << 0),
156 };
157 
158 /*
159  * FTL device attributes.
160  *
161  * NOTE: Do not change the layout of this structure. Only add new fields at the end.
162  */
163 struct spdk_ftl_attrs {
164 	/* Number of logical blocks */
165 	uint64_t			num_blocks;
166 	/* Logical block size */
167 	uint64_t			block_size;
168 	/* Optimal IO size - bdev layer will split requests over this size */
169 	uint64_t			optimum_io_size;
170 };
171 
172 typedef void (*spdk_ftl_fn)(void *cb_arg, int status);
173 typedef void (*spdk_ftl_init_fn)(struct spdk_ftl_dev *dev, void *cb_arg, int status);
174 
175 /**
176  * Initializes the FTL library.
177  *
178  * @return 0 on success, negative errno otherwise.
179  */
180 int spdk_ftl_init(void);
181 
182 /**
183  * Deinitializes the FTL library.
184  */
185 void spdk_ftl_fini(void);
186 
187 /**
188  * Initialize the FTL on the given pair of bdevs - base and cache bdev.
189  * Upon receiving a successful completion callback user is free to use I/O calls.
190  *
191  * \param conf configuration for new device
192  * \param cb callback function to call when the device is created
193  * \param cb_arg callback's argument
194  *
195  * \return 0 if initialization was started successfully, negative errno otherwise.
196  */
197 int spdk_ftl_dev_init(const struct spdk_ftl_conf *conf, spdk_ftl_init_fn cb, void *cb_arg);
198 
199 /**
200  * Deinitialize and free given device.
201  *
202  * \param dev device
203  * \param cb callback function to call when the device is freed
204  * \param cb_arg callback's argument
205  *
206  * \return 0 if deinitialization was started successfully, negative errno otherwise.
207  */
208 int spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_fn cb, void *cb_arg);
209 
210 /**
211  * Retrieve device’s attributes.
212  *
213  * \param dev device
214  * \param attr Attribute structure to fill
215  * \param attrs_size Must be set to sizeof(struct spdk_ftl_attrs)
216  */
217 void spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *attr,
218 			    size_t attrs_size);
219 
220 /**
221  * Retrieve device’s configuration.
222  *
223  * \param dev device
224  * \param conf FTL configuration structure to fill
225  * \param conf_size Must be set to sizeof(struct spdk_ftl_conf)
226  */
227 void spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf,
228 			   size_t conf_size);
229 
230 /**
231  * Obtain an I/O channel for the device.
232  *
233  * \param dev device
234  *
235  * \return A handle to the I/O channel or NULL on failure.
236  */
237 struct spdk_io_channel *spdk_ftl_get_io_channel(struct spdk_ftl_dev *dev);
238 
239 /**
240  * Make a deep copy of an FTL configuration structure
241  *
242  * \param dst The destination FTL configuration
243  * \param src The source FTL configuration
244  */
245 int spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src);
246 
247 /**
248  * Release the FTL configuration resources. This does not free the structure itself.
249  *
250  * \param conf FTL configuration to deinitialize
251  */
252 void spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf);
253 
254 /**
255  * Initialize FTL configuration structure with default values.
256  *
257  * \param conf FTL configuration to initialize
258  * \param conf_size Must be set to sizeof(struct spdk_ftl_conf)
259  */
260 void spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf, size_t conf_size);
261 
262 /**
263  * Submits a read to the specified device.
264  *
265  * \param dev Device
266  * \param io Allocated ftl_io
267  * \param ch I/O channel
268  * \param lba Starting LBA to read the data
269  * \param lba_cnt Number of sectors to read
270  * \param iov Single IO vector or pointer to IO vector table
271  * \param iov_cnt Number of IO vectors
272  * \param cb_fn Callback function to invoke when the I/O is completed
273  * \param cb_arg Argument to pass to the callback function
274  *
275  * \return 0 if successfully submitted, negative errno otherwise.
276  */
277 int spdk_ftl_readv(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch,
278 		   uint64_t lba, uint64_t lba_cnt,
279 		   struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg);
280 
281 /**
282  * Submits a write to the specified device.
283  *
284  * \param dev Device
285  * \param io Allocated ftl_io
286  * \param ch I/O channel
287  * \param lba Starting LBA to write the data
288  * \param lba_cnt Number of sectors to write
289  * \param iov Single IO vector or pointer to IO vector table
290  * \param iov_cnt Number of IO vectors
291  * \param cb_fn Callback function to invoke when the I/O is completed
292  * \param cb_arg Argument to pass to the callback function
293  *
294  * \return 0 if successfully submitted, negative errno otherwise.
295  */
296 int spdk_ftl_writev(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch,
297 		    uint64_t lba, uint64_t lba_cnt,
298 		    struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg);
299 
300 /**
301  * Submits a unmap to the specified device.
302  *
303  * \param dev Device
304  * \param io Allocated ftl_io
305  * \param ch I/O channel
306  * \param lba Starting LBA to write the data
307  * \param lba_cnt Number of blocks to unmap
308  * \param cb_fn Callback function to invoke when the I/O is completed
309  * \param cb_arg Argument to pass to the callback function
310  *
311  * \return 0 if successfully submitted, negative errno otherwise.
312  */
313 int spdk_ftl_unmap(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch,
314 		   uint64_t lba, uint64_t lba_cnt, spdk_ftl_fn cb_fn, void *cb_arg);
315 
316 /**
317  * Returns the size of ftl_io struct that needs to be passed to spdk_ftl_read/write
318  *
319  * \return The size of struct
320  */
321 size_t spdk_ftl_io_size(void);
322 
323 /**
324  * Enable fast shutdown.
325  *
326  * During fast shutdown FTL will keep the necessary metadata in shared memory instead
327  * of serializing it to storage. This allows for shorter downtime during upgrade process.
328  */
329 void spdk_ftl_dev_set_fast_shutdown(struct spdk_ftl_dev *dev, bool fast_shutdown);
330 
331 /*
332  * Returns current FTL I/O statistics.
333  *
334  * \param dev Device
335  * \param stats Allocated ftl_stats
336  * \param cb_fn Callback function to invoke when the call is completed
337  * \param cb_arg Argument to pass to the callback function
338  *
339  * \return 0 if successfully submitted, negative errno otherwise.
340  */
341 int spdk_ftl_get_stats(struct spdk_ftl_dev *dev, struct ftl_stats *stats, spdk_ftl_stats_fn cb_fn,
342 		       void *cb_arg);
343 
344 /**
345  * Gets properties of the specified device.
346  *
347  * \param dev FTL device
348  * \param request JSON RPC request where the properties will be stored
349  * \param cb_fn Callback function to invoke when the operation is completed
350  * \param cb_arg Argument to pass to the callback function
351  *
352  * \return 0 if successfully submitted, negative errno otherwise.
353  */
354 int spdk_ftl_get_properties(struct spdk_ftl_dev *dev, struct spdk_jsonrpc_request *request,
355 			    spdk_ftl_fn cb_fn, void *cb_arg);
356 
357 /**
358  * Sets the property of the specified device.
359  *
360  * \param dev FTL device
361  * \param property The property name to be modified
362  * \param value The new value to property
363  * \param value_size The size of the value buffer
364  * \param cb_fn Callback function to invoke when the operation is completed
365  * \param cb_arg Argument to pass to the callback function
366  *
367  * \return 0 if successfully submitted, negative errno otherwise.
368  */
369 int spdk_ftl_set_property(struct spdk_ftl_dev *dev, const char *property, const char *value,
370 			  size_t value_size, spdk_ftl_fn cb_fn, void *cb_arg);
371 
372 #ifdef __cplusplus
373 }
374 #endif
375 
376 #endif /* SPDK_FTL_H */
377