xref: /spdk/lib/ftl/ftl_core.h (revision fa09c9ac9b0ce66dcacb64b02aae778014b6c2b3)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #ifndef FTL_CORE_H
7 #define FTL_CORE_H
8 
9 #include "spdk/stdinc.h"
10 #include "spdk/uuid.h"
11 #include "spdk/thread.h"
12 #include "spdk/util.h"
13 #include "spdk/likely.h"
14 #include "spdk/queue.h"
15 #include "spdk/ftl.h"
16 #include "spdk/bdev.h"
17 #include "spdk/bdev_zone.h"
18 
19 #include "ftl_internal.h"
20 #include "ftl_io.h"
21 #include "ftl_layout.h"
22 #include "ftl_sb.h"
23 #include "utils/ftl_log.h"
24 
25 /* When using VSS on nvcache, FTL sometimes doesn't require the contents of metadata.
26  * Some devices have bugs when sending a NULL pointer as part of metadata when namespace
27  * is formatted with VSS. This buffer is passed to such calls to avoid the bug. */
28 #define FTL_ZERO_BUFFER_SIZE 0x100000
29 extern void *g_ftl_write_buf;
30 extern void *g_ftl_read_buf;
31 
32 struct spdk_ftl_dev {
33 	/* Configuration */
34 	struct spdk_ftl_conf		conf;
35 
36 	/* FTL device layout */
37 	struct ftl_layout		layout;
38 
39 	/* FTL superblock */
40 	struct ftl_superblock		*sb;
41 
42 	/* Queue of registered IO channels */
43 	TAILQ_HEAD(, ftl_io_channel)	ioch_queue;
44 
45 	/* Underlying device */
46 	struct spdk_bdev_desc		*base_bdev_desc;
47 
48 	/* Cache device */
49 	struct spdk_bdev_desc		*cache_bdev_desc;
50 
51 	/* Cache VSS metadata size */
52 	uint64_t			cache_md_size;
53 
54 	/* Cached properties of the underlying device */
55 	uint64_t			num_blocks_in_band;
56 	uint64_t			num_zones_in_band;
57 	uint64_t			num_blocks_in_zone;
58 	bool				is_zoned;
59 
60 	/* Indicates the device is fully initialized */
61 	bool				initialized;
62 
63 	/* Indicates the device is about to be stopped */
64 	bool				halt;
65 
66 	/* Indicates if the device is registered as an IO device */
67 	bool				io_device_registered;
68 
69 	/* Management process to be continued after IO device unregistration completes */
70 	struct ftl_mngt_process		*unregister_process;
71 
72 	/* counters for poller busy, include
73 	   1. nv cache read/write
74 	   2. metadata read/write
75 	   3. base bdev read/write */
76 	uint64_t			io_activity_total;
77 
78 	/* Number of operational bands */
79 	uint64_t			num_bands;
80 
81 	/* Number of free bands */
82 	uint64_t			num_free;
83 
84 	/* Size of the l2p table */
85 	uint64_t			num_lbas;
86 
87 	/* Metadata size */
88 	uint64_t			md_size;
89 
90 	/* Transfer unit size */
91 	uint64_t			xfer_size;
92 
93 	/* Inflight IO operations */
94 	uint32_t			num_inflight;
95 
96 	/* Thread on which the poller is running */
97 	struct spdk_thread		*core_thread;
98 
99 	/* IO channel to the FTL device, used for internal management operations
100 	 * consuming FTL's external API
101 	 */
102 	struct spdk_io_channel		*ioch;
103 
104 	/* Underlying device IO channel */
105 	struct spdk_io_channel		*base_ioch;
106 
107 	/* Cache IO channel */
108 	struct spdk_io_channel		*cache_ioch;
109 
110 	/* Poller */
111 	struct spdk_poller		*core_poller;
112 
113 	/* Read submission queue */
114 	TAILQ_HEAD(, ftl_io)		rd_sq;
115 
116 	/* Write submission queue */
117 	TAILQ_HEAD(, ftl_io)		wr_sq;
118 };
119 
120 int ftl_core_poller(void *ctx);
121 
122 int ftl_io_channel_poll(void *arg);
123 
124 struct ftl_io_channel *ftl_io_channel_get_ctx(struct spdk_io_channel *ioch);
125 
126 static inline uint64_t
127 ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
128 {
129 	return dev->num_blocks_in_band;
130 }
131 
132 static inline size_t
133 ftl_get_num_zones_in_band(const struct spdk_ftl_dev *dev)
134 {
135 	return dev->num_zones_in_band;
136 }
137 
138 static inline size_t
139 ftl_get_num_blocks_in_zone(const struct spdk_ftl_dev *dev)
140 {
141 	return dev->num_blocks_in_zone;
142 }
143 
144 static inline uint32_t
145 ftl_get_write_unit_size(struct spdk_bdev *bdev)
146 {
147 	if (spdk_bdev_is_zoned(bdev)) {
148 		return spdk_bdev_get_write_unit_size(bdev);
149 	}
150 
151 	/* TODO: this should be passed via input parameter */
152 	return 32;
153 }
154 
155 static inline struct spdk_thread *
156 ftl_get_core_thread(const struct spdk_ftl_dev *dev)
157 {
158 	return dev->core_thread;
159 }
160 
161 static inline size_t
162 ftl_get_num_bands(const struct spdk_ftl_dev *dev)
163 {
164 	return dev->num_bands;
165 }
166 
167 static inline size_t
168 ftl_get_num_zones(const struct spdk_ftl_dev *dev)
169 {
170 	return ftl_get_num_bands(dev) * ftl_get_num_zones_in_band(dev);
171 }
172 
173 static inline bool
174 ftl_check_core_thread(const struct spdk_ftl_dev *dev)
175 {
176 	return dev->core_thread == spdk_get_thread();
177 }
178 
179 #endif /* FTL_CORE_H */
180