xref: /spdk/lib/ftl/ftl_io.h (revision 9889ab2dc80e40dae92dcef361d53dcba722043d)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef FTL_IO_H
35 #define FTL_IO_H
36 
37 #include "spdk/stdinc.h"
38 #include "spdk/nvme.h"
39 #include "spdk/ftl.h"
40 
41 #include "ftl_ppa.h"
42 #include "ftl_trace.h"
43 
44 struct spdk_ftl_dev;
45 struct ftl_rwb_batch;
46 struct ftl_band;
47 struct ftl_io;
48 
49 typedef int (*ftl_md_pack_fn)(struct ftl_band *);
50 typedef void (*ftl_io_fn)(struct ftl_io *, void *, int);
51 
52 /* IO flags */
53 enum ftl_io_flags {
54 	/* Indicates whether IO is already initialized */
55 	FTL_IO_INITIALIZED	= (1 << 0),
56 	/* Internal based IO (defrag, metadata etc.) */
57 	FTL_IO_INTERNAL		= (1 << 1),
58 	/* Indicates that the IO should not go through if there's */
59 	/* already another one scheduled to the same LBA */
60 	FTL_IO_WEAK		= (1 << 2),
61 	/* Indicates that the IO is used for padding */
62 	FTL_IO_PAD		= (1 << 3),
63 	/* The IO operates on metadata */
64 	FTL_IO_MD		= (1 << 4),
65 	/* Using PPA instead of LBA */
66 	FTL_IO_PPA_MODE		= (1 << 5),
67 	/* Indicates that IO contains noncontiguous LBAs */
68 	FTL_IO_VECTOR_LBA	= (1 << 6),
69 	/* Indicates that IO is being retried */
70 	FTL_IO_RETRY		= (1 << 7),
71 	/* The IO is directed to non-volatile cache */
72 	FTL_IO_CACHE		= (1 << 8),
73 	/* Indicates that PPA should be taken from IO struct, */
74 	/* not assigned by wptr, only works if wptr is also in direct mode */
75 	FTL_IO_DIRECT_ACCESS	= (1 << 9),
76 	/* Bypass the non-volatile cache */
77 	FTL_IO_BYPASS_CACHE	= (1 << 10),
78 };
79 
80 enum ftl_io_type {
81 	FTL_IO_READ,
82 	FTL_IO_WRITE,
83 	FTL_IO_ERASE,
84 };
85 
86 struct ftl_io_init_opts {
87 	struct spdk_ftl_dev			*dev;
88 
89 	/* IO descriptor */
90 	struct ftl_io				*io;
91 
92 	/* Parent request */
93 	struct ftl_io				*parent;
94 
95 	/* Size of IO descriptor */
96 	size_t                                  size;
97 
98 	/* IO flags */
99 	int                                     flags;
100 
101 	/* IO type */
102 	enum ftl_io_type			type;
103 
104 	/* RWB entry */
105 	struct ftl_rwb_batch			*rwb_batch;
106 
107 	/* Band to which the IO is directed */
108 	struct ftl_band				*band;
109 
110 	/* Number of logical blocks */
111 	size_t                                  lbk_cnt;
112 
113 	/* Data */
114 	void                                    *data;
115 
116 	/* Metadata */
117 	void                                    *md;
118 
119 	/* Callback's function */
120 	ftl_io_fn				cb_fn;
121 
122 	/* Callback's context */
123 	void					*cb_ctx;
124 };
125 
126 struct ftl_io_channel {
127 	/* Device */
128 	struct spdk_ftl_dev			*dev;
129 	/* IO pool element size */
130 	size_t					elem_size;
131 	/* IO pool */
132 	struct spdk_mempool			*io_pool;
133 	/* Persistent cache IO channel */
134 	struct spdk_io_channel			*cache_ioch;
135 };
136 
137 /* General IO descriptor */
138 struct ftl_io {
139 	/* Device */
140 	struct spdk_ftl_dev			*dev;
141 
142 	/* IO channel */
143 	struct spdk_io_channel			*ioch;
144 
145 	union {
146 		/* LBA table */
147 		uint64_t			*vector;
148 
149 		/* First LBA */
150 		uint64_t			single;
151 	} lba;
152 
153 	/* First PPA */
154 	struct ftl_ppa				ppa;
155 
156 	/* Number of processed lbks */
157 	size_t					pos;
158 
159 	/* Number of lbks */
160 	size_t					lbk_cnt;
161 
162 #define FTL_IO_MAX_IOVEC 64
163 	struct iovec				iov[FTL_IO_MAX_IOVEC];
164 
165 	/* Metadata */
166 	void					*md;
167 
168 	/* Number of IO vectors */
169 	size_t					iov_cnt;
170 
171 	/* Position within the iovec */
172 	size_t					iov_pos;
173 
174 	/* Offset within the iovec (in lbks) */
175 	size_t					iov_off;
176 
177 	/* RWB entry (valid only for RWB-based IO) */
178 	struct ftl_rwb_batch			*rwb_batch;
179 
180 	/* Band this IO is being written to */
181 	struct ftl_band				*band;
182 
183 	/* Request status */
184 	int					status;
185 
186 	/* Number of split requests */
187 	size_t					req_cnt;
188 
189 	/* Callback's function */
190 	ftl_io_fn				cb_fn;
191 
192 	/* Callback's context */
193 	void					*cb_ctx;
194 
195 	/* User callback function */
196 	spdk_ftl_fn				user_fn;
197 
198 	/* Flags */
199 	int					flags;
200 
201 	/* IO type */
202 	enum ftl_io_type			type;
203 
204 	/* Done flag */
205 	bool					done;
206 
207 	/* Parent request */
208 	struct ftl_io				*parent;
209 	/* Child requests list */
210 	LIST_HEAD(, ftl_io)			children;
211 	/* Child list link */
212 	LIST_ENTRY(ftl_io)			child_entry;
213 	/* Children lock */
214 	pthread_spinlock_t			lock;
215 
216 	/* Trace group id */
217 	uint64_t				trace;
218 
219 	TAILQ_ENTRY(ftl_io)			retry_entry;
220 };
221 
222 /* Metadata IO */
223 struct ftl_md_io {
224 	/* Parent IO structure */
225 	struct ftl_io				io;
226 
227 	/* Serialization/deserialization callback */
228 	ftl_md_pack_fn				pack_fn;
229 
230 	/* Callback's function */
231 	ftl_io_fn				cb_fn;
232 
233 	/* Callback's context */
234 	void					*cb_ctx;
235 };
236 
237 static inline bool
238 ftl_io_mode_ppa(const struct ftl_io *io)
239 {
240 	return io->flags & FTL_IO_PPA_MODE;
241 }
242 
243 static inline bool
244 ftl_io_mode_lba(const struct ftl_io *io)
245 {
246 	return !ftl_io_mode_ppa(io);
247 }
248 
249 static inline bool
250 ftl_io_done(const struct ftl_io *io)
251 {
252 	return io->req_cnt == 0 &&
253 	       io->pos == io->lbk_cnt &&
254 	       !(io->flags & FTL_IO_RETRY);
255 }
256 
257 struct ftl_io *ftl_io_alloc(struct spdk_io_channel *ch);
258 struct ftl_io *ftl_io_alloc_child(struct ftl_io *parent);
259 void ftl_io_fail(struct ftl_io *io, int status);
260 void ftl_io_free(struct ftl_io *io);
261 struct ftl_io *ftl_io_init_internal(const struct ftl_io_init_opts *opts);
262 void ftl_io_reinit(struct ftl_io *io, ftl_io_fn cb,
263 		   void *ctx, int flags, int type);
264 void ftl_io_clear(struct ftl_io *io);
265 void ftl_io_inc_req(struct ftl_io *io);
266 void ftl_io_dec_req(struct ftl_io *io);
267 struct iovec *ftl_io_iovec(struct ftl_io *io);
268 uint64_t ftl_io_current_lba(const struct ftl_io *io);
269 uint64_t ftl_io_get_lba(const struct ftl_io *io, size_t offset);
270 void ftl_io_advance(struct ftl_io *io, size_t lbk_cnt);
271 size_t ftl_iovec_num_lbks(struct iovec *iov, size_t iov_cnt);
272 void *ftl_io_iovec_addr(struct ftl_io *io);
273 size_t ftl_io_iovec_len_left(struct ftl_io *io);
274 struct ftl_io *ftl_io_rwb_init(struct spdk_ftl_dev *dev, struct ftl_band *band,
275 			       struct ftl_rwb_batch *entry, ftl_io_fn cb);
276 struct ftl_io *ftl_io_erase_init(struct ftl_band *band, size_t lbk_cnt, ftl_io_fn cb);
277 struct ftl_io *ftl_io_user_init(struct spdk_io_channel *ioch, uint64_t lba, size_t lbk_cnt,
278 				struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn,
279 				void *cb_arg, int type);
280 void *ftl_io_get_md(const struct ftl_io *io);
281 void ftl_io_complete(struct ftl_io *io);
282 void ftl_io_shrink_iovec(struct ftl_io *io, size_t lbk_cnt);
283 void ftl_io_process_error(struct ftl_io *io, const struct spdk_nvme_cpl *status);
284 void ftl_io_reset(struct ftl_io *io);
285 void ftl_io_call_foreach_child(struct ftl_io *io, int (*callback)(struct ftl_io *));
286 
287 #endif /* FTL_IO_H */
288