xref: /spdk/lib/ftl/ftl_io.h (revision bb488d2829a9b7863daab45917dd2174905cc0ae)
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 struct ftl_md;
49 
50 typedef int (*ftl_md_pack_fn)(struct spdk_ftl_dev *, struct ftl_md *, void *);
51 
52 /* IO flags */
53 enum ftl_io_flags {
54 	/* Indicates whether IO is already initialized */
55 	FTL_IO_INITIALIZED	= (1 << 0),
56 	/* Keep the IO when done with the request */
57 	FTL_IO_KEEP_ALIVE	= (1 << 1),
58 	/* Internal based IO (defrag, metadata etc.) */
59 	FTL_IO_INTERNAL		= (1 << 2),
60 	/* Indicates that the IO should not go through if there's */
61 	/* already another one scheduled to the same LBA */
62 	FTL_IO_WEAK		= (1 << 3),
63 	/* Indicates that the IO is used for padding */
64 	FTL_IO_PAD		= (1 << 4),
65 	/* The IO operates on metadata */
66 	FTL_IO_MD		= (1 << 5),
67 	/* Using PPA instead of LBA */
68 	FTL_IO_PPA_MODE		= (1 << 6),
69 	/* Indicates that IO contains noncontiguous LBAs */
70 	FTL_IO_VECTOR_LBA	= (1 << 7),
71 	/* Indicates that IO is being retried */
72 	FTL_IO_RETRY		= (1 << 8),
73 };
74 
75 enum ftl_io_type {
76 	FTL_IO_READ,
77 	FTL_IO_WRITE,
78 	FTL_IO_ERASE,
79 };
80 
81 struct ftl_io_init_opts {
82 	struct spdk_ftl_dev			*dev;
83 
84 	/* IO descriptor */
85 	struct ftl_io				*io;
86 
87 	/* Size of IO descriptor */
88 	size_t                                  size;
89 
90 	/* IO flags */
91 	int                                     flags;
92 
93 	/* IO type */
94 	enum ftl_io_type			type;
95 
96 	/* Number of split requests */
97 	size_t                                  iov_cnt;
98 
99 	/* RWB entry */
100 	struct ftl_rwb_batch			*rwb_batch;
101 
102 	/* Band to which the IO is directed */
103 	struct ftl_band				*band;
104 
105 	/* Request size */
106 	size_t                                  req_size;
107 
108 	/* Data */
109 	void                                    *data;
110 
111 	/* Metadata */
112 	void                                    *md;
113 
114 	/* Callback */
115 	spdk_ftl_fn				fn;
116 };
117 
118 struct ftl_cb {
119 	/* Callback function */
120 	spdk_ftl_fn				fn;
121 
122 	/* Callback's context */
123 	void					*ctx;
124 };
125 
126 struct ftl_io_channel {
127 	/* IO pool element size */
128 	size_t					elem_size;
129 
130 	/* IO pool */
131 	struct spdk_mempool			*io_pool;
132 };
133 
134 /* General IO descriptor */
135 struct ftl_io {
136 	/* Device */
137 	struct spdk_ftl_dev			*dev;
138 
139 	/* IO channel */
140 	struct spdk_io_channel			*ch;
141 
142 	union {
143 		/* LBA table */
144 		uint64_t			*lbas;
145 
146 		/* First LBA */
147 		uint64_t			lba;
148 	};
149 
150 	/* First PPA */
151 	struct ftl_ppa				ppa;
152 
153 	/* Number of processed lbks */
154 	size_t					pos;
155 
156 	/* Number of lbks */
157 	size_t					lbk_cnt;
158 
159 	union {
160 		/* IO vector table */
161 		struct iovec			*iovs;
162 
163 		/* Single iovec */
164 		struct iovec			iov;
165 	};
166 
167 	/* Metadata */
168 	void					*md;
169 
170 	/* Number of IO vectors */
171 	size_t					iov_cnt;
172 
173 	/* Position within the iovec */
174 	size_t					iov_pos;
175 
176 	/* Offset within the iovec (in lbks) */
177 	size_t					iov_off;
178 
179 	/* RWB entry (valid only for RWB-based IO) */
180 	struct ftl_rwb_batch			*rwb_batch;
181 
182 	/* Band this IO is being written to */
183 	struct ftl_band				*band;
184 
185 	/* Request status */
186 	int					status;
187 
188 	/* Number of split requests */
189 	size_t					req_cnt;
190 
191 	/* Completion callback */
192 	struct ftl_cb				cb;
193 
194 	/* Flags */
195 	int					flags;
196 
197 	/* IO type */
198 	enum ftl_io_type			type;
199 
200 	/* Trace group id */
201 	uint64_t				trace;
202 
203 	TAILQ_ENTRY(ftl_io)			retry_entry;
204 };
205 
206 /* Metadata IO */
207 struct ftl_md_io {
208 	/* Parent IO structure */
209 	struct ftl_io				io;
210 
211 	/* Destination metadata pointer */
212 	struct ftl_md				*md;
213 
214 	/* Metadata's buffer */
215 	void					*buf;
216 
217 	/* Serialization/deserialization callback */
218 	ftl_md_pack_fn				pack_fn;
219 
220 	/* User's callback */
221 	struct ftl_cb				cb;
222 };
223 
224 static inline bool
225 ftl_io_mode_ppa(const struct ftl_io *io)
226 {
227 	return io->flags & FTL_IO_PPA_MODE;
228 }
229 
230 static inline bool
231 ftl_io_mode_lba(const struct ftl_io *io)
232 {
233 	return !ftl_io_mode_ppa(io);
234 }
235 
236 static inline bool
237 ftl_io_done(const struct ftl_io *io)
238 {
239 	return io->req_cnt == 0 && !(io->flags & FTL_IO_RETRY);
240 }
241 
242 struct ftl_io *ftl_io_alloc(struct spdk_io_channel *ch);
243 void ftl_io_free(struct ftl_io *io);
244 struct ftl_io *ftl_io_init_internal(const struct ftl_io_init_opts *opts);
245 void ftl_io_reinit(struct ftl_io *io, spdk_ftl_fn cb,
246 		   void *ctx, int flags, int type);
247 void ftl_io_clear(struct ftl_io *io);
248 void ftl_io_inc_req(struct ftl_io *io);
249 void ftl_io_dec_req(struct ftl_io *io);
250 struct iovec *ftl_io_iovec(struct ftl_io *io);
251 uint64_t ftl_io_current_lba(struct ftl_io *io);
252 void ftl_io_update_iovec(struct ftl_io *io, size_t lbk_cnt);
253 size_t ftl_iovec_num_lbks(struct iovec *iov, size_t iov_cnt);
254 void *ftl_io_iovec_addr(struct ftl_io *io);
255 size_t ftl_io_iovec_len_left(struct ftl_io *io);
256 int ftl_io_init_iovec(struct ftl_io *io, void *buf,
257 		      size_t iov_cnt, size_t req_size);
258 struct ftl_io *ftl_io_init_internal(const struct ftl_io_init_opts *opts);
259 struct ftl_io *ftl_io_rwb_init(struct spdk_ftl_dev *dev, struct ftl_band *band,
260 			       struct ftl_rwb_batch *entry, spdk_ftl_fn cb);
261 struct ftl_io *ftl_io_erase_init(struct ftl_band *band, size_t lbk_cnt, spdk_ftl_fn cb);
262 void ftl_io_user_init(struct spdk_ftl_dev *dev, struct ftl_io *io, uint64_t lba, size_t lbk_cnt,
263 		      struct iovec *iov, size_t iov_cnt,
264 		      spdk_ftl_fn fn, void *cb_arg, int type);
265 void *ftl_io_get_md(const struct ftl_io *io);
266 void ftl_io_complete(struct ftl_io *io);
267 void ftl_io_process_error(struct ftl_io *io, const struct spdk_nvme_cpl *status);
268 
269 #endif /* FTL_IO_H */
270