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