]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/ftl/ftl_io.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / lib / ftl / ftl_io.h
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 };
77
78 enum ftl_io_type {
79 FTL_IO_READ,
80 FTL_IO_WRITE,
81 FTL_IO_ERASE,
82 };
83
84 struct ftl_io_init_opts {
85 struct spdk_ftl_dev *dev;
86
87 /* IO descriptor */
88 struct ftl_io *io;
89
90 /* Parent request */
91 struct ftl_io *parent;
92
93 /* Size of IO descriptor */
94 size_t size;
95
96 /* IO flags */
97 int flags;
98
99 /* IO type */
100 enum ftl_io_type type;
101
102 /* RWB entry */
103 struct ftl_rwb_batch *rwb_batch;
104
105 /* Band to which the IO is directed */
106 struct ftl_band *band;
107
108 /* Number of logical blocks */
109 size_t lbk_cnt;
110
111 /* Data */
112 void *data;
113
114 /* Metadata */
115 void *md;
116
117 /* Callback's function */
118 ftl_io_fn cb_fn;
119
120 /* Callback's context */
121 void *cb_ctx;
122 };
123
124 struct ftl_io_channel {
125 /* Device */
126 struct spdk_ftl_dev *dev;
127 /* IO pool element size */
128 size_t elem_size;
129 /* IO pool */
130 struct spdk_mempool *io_pool;
131 /* Persistent cache IO channel */
132 struct spdk_io_channel *cache_ioch;
133 };
134
135 /* General IO descriptor */
136 struct ftl_io {
137 /* Device */
138 struct spdk_ftl_dev *dev;
139
140 /* IO channel */
141 struct spdk_io_channel *ioch;
142
143 union {
144 /* LBA table */
145 uint64_t *vector;
146
147 /* First LBA */
148 uint64_t single;
149 } lba;
150
151 /* First PPA */
152 struct ftl_ppa ppa;
153
154 /* Number of processed lbks */
155 size_t pos;
156
157 /* Number of lbks */
158 size_t lbk_cnt;
159
160 #define FTL_IO_MAX_IOVEC 64
161 struct iovec iov[FTL_IO_MAX_IOVEC];
162
163 /* Metadata */
164 void *md;
165
166 /* Number of IO vectors */
167 size_t iov_cnt;
168
169 /* Position within the iovec */
170 size_t iov_pos;
171
172 /* Offset within the iovec (in lbks) */
173 size_t iov_off;
174
175 /* RWB entry (valid only for RWB-based IO) */
176 struct ftl_rwb_batch *rwb_batch;
177
178 /* Band this IO is being written to */
179 struct ftl_band *band;
180
181 /* Request status */
182 int status;
183
184 /* Number of split requests */
185 size_t req_cnt;
186
187 /* Callback's function */
188 ftl_io_fn cb_fn;
189
190 /* Callback's context */
191 void *cb_ctx;
192
193 /* User callback function */
194 spdk_ftl_fn user_fn;
195
196 /* Flags */
197 int flags;
198
199 /* IO type */
200 enum ftl_io_type type;
201
202 /* Done flag */
203 bool done;
204
205 /* Parent request */
206 struct ftl_io *parent;
207 /* Child requests list */
208 LIST_HEAD(, ftl_io) children;
209 /* Child list link */
210 LIST_ENTRY(ftl_io) child_entry;
211 /* Children lock */
212 pthread_spinlock_t lock;
213
214 /* Trace group id */
215 uint64_t trace;
216
217 TAILQ_ENTRY(ftl_io) retry_entry;
218 };
219
220 /* Metadata IO */
221 struct ftl_md_io {
222 /* Parent IO structure */
223 struct ftl_io io;
224
225 /* Serialization/deserialization callback */
226 ftl_md_pack_fn pack_fn;
227
228 /* Callback's function */
229 ftl_io_fn cb_fn;
230
231 /* Callback's context */
232 void *cb_ctx;
233 };
234
235 static inline bool
236 ftl_io_mode_ppa(const struct ftl_io *io)
237 {
238 return io->flags & FTL_IO_PPA_MODE;
239 }
240
241 static inline bool
242 ftl_io_mode_lba(const struct ftl_io *io)
243 {
244 return !ftl_io_mode_ppa(io);
245 }
246
247 static inline bool
248 ftl_io_done(const struct ftl_io *io)
249 {
250 return io->req_cnt == 0 &&
251 io->pos == io->lbk_cnt &&
252 !(io->flags & FTL_IO_RETRY);
253 }
254
255 struct ftl_io *ftl_io_alloc(struct spdk_io_channel *ch);
256 struct ftl_io *ftl_io_alloc_child(struct ftl_io *parent);
257 void ftl_io_fail(struct ftl_io *io, int status);
258 void ftl_io_free(struct ftl_io *io);
259 struct ftl_io *ftl_io_init_internal(const struct ftl_io_init_opts *opts);
260 void ftl_io_reinit(struct ftl_io *io, ftl_io_fn cb,
261 void *ctx, int flags, int type);
262 void ftl_io_clear(struct ftl_io *io);
263 void ftl_io_inc_req(struct ftl_io *io);
264 void ftl_io_dec_req(struct ftl_io *io);
265 struct iovec *ftl_io_iovec(struct ftl_io *io);
266 uint64_t ftl_io_current_lba(const struct ftl_io *io);
267 uint64_t ftl_io_get_lba(const struct ftl_io *io, size_t offset);
268 void ftl_io_advance(struct ftl_io *io, size_t lbk_cnt);
269 size_t ftl_iovec_num_lbks(struct iovec *iov, size_t iov_cnt);
270 void *ftl_io_iovec_addr(struct ftl_io *io);
271 size_t ftl_io_iovec_len_left(struct ftl_io *io);
272 struct ftl_io *ftl_io_rwb_init(struct spdk_ftl_dev *dev, struct ftl_band *band,
273 struct ftl_rwb_batch *entry, ftl_io_fn cb);
274 struct ftl_io *ftl_io_erase_init(struct ftl_band *band, size_t lbk_cnt, ftl_io_fn cb);
275 struct ftl_io *ftl_io_user_init(struct spdk_io_channel *ioch, uint64_t lba, size_t lbk_cnt,
276 struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn,
277 void *cb_arg, int type);
278 void *ftl_io_get_md(const struct ftl_io *io);
279 void ftl_io_complete(struct ftl_io *io);
280 void ftl_io_shrink_iovec(struct ftl_io *io, size_t lbk_cnt);
281 void ftl_io_process_error(struct ftl_io *io, const struct spdk_nvme_cpl *status);
282 void ftl_io_reset(struct ftl_io *io);
283 void ftl_io_call_foreach_child(struct ftl_io *io, int (*callback)(struct ftl_io *));
284
285 #endif /* FTL_IO_H */