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 SPDK_FTL_H 35 #define SPDK_FTL_H 36 37 #include "spdk/stdinc.h" 38 #include "spdk/nvme.h" 39 #include "spdk/nvme_ocssd.h" 40 #include "spdk/uuid.h" 41 #include "spdk/thread.h" 42 #include "spdk/bdev.h" 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 struct spdk_ftl_dev; 49 50 /* Limit thresholds */ 51 enum { 52 SPDK_FTL_LIMIT_CRIT, 53 SPDK_FTL_LIMIT_HIGH, 54 SPDK_FTL_LIMIT_LOW, 55 SPDK_FTL_LIMIT_START, 56 SPDK_FTL_LIMIT_MAX 57 }; 58 59 struct spdk_ftl_limit { 60 /* Threshold from which the limiting starts */ 61 size_t thld; 62 63 /* Limit percentage */ 64 size_t limit; 65 }; 66 67 struct spdk_ftl_conf { 68 /* Number of reserved addresses not exposed to the user */ 69 size_t lba_rsvd; 70 71 /* Write buffer size */ 72 size_t rwb_size; 73 74 /* Threshold for opening new band */ 75 size_t band_thld; 76 77 /* Maximum IO depth per band relocate */ 78 size_t max_reloc_qdepth; 79 80 /* Maximum active band relocates */ 81 size_t max_active_relocs; 82 83 /* IO pool size per user thread */ 84 size_t user_io_pool_size; 85 86 /* Lowest percentage of invalid lbks for a band to be defragged */ 87 size_t invalid_thld; 88 89 /* User writes limits */ 90 struct spdk_ftl_limit limits[SPDK_FTL_LIMIT_MAX]; 91 92 /* Number of interleaving units per ws_opt */ 93 size_t num_interleave_units; 94 95 /* Allow for partial recovery from open bands instead of returning error */ 96 bool allow_open_bands; 97 98 struct { 99 /* Maximum number of concurrent requests */ 100 size_t max_request_cnt; 101 /* Maximum number of blocks per one request */ 102 size_t max_request_size; 103 } nv_cache; 104 }; 105 106 /* Range of parallel units (inclusive) */ 107 struct spdk_ftl_punit_range { 108 unsigned int begin; 109 unsigned int end; 110 }; 111 112 enum spdk_ftl_mode { 113 /* Create new device */ 114 SPDK_FTL_MODE_CREATE = (1 << 0), 115 }; 116 117 struct spdk_ftl_dev_init_opts { 118 /* NVMe controller */ 119 struct spdk_nvme_ctrlr *ctrlr; 120 /* Controller's transport ID */ 121 struct spdk_nvme_transport_id trid; 122 /* Write buffer cache */ 123 struct spdk_bdev_desc *cache_bdev_desc; 124 125 /* Thread responsible for core tasks execution */ 126 struct spdk_thread *core_thread; 127 /* Thread responsible for read requests */ 128 struct spdk_thread *read_thread; 129 130 /* Device's config */ 131 const struct spdk_ftl_conf *conf; 132 /* Device's name */ 133 const char *name; 134 /* Parallel unit range */ 135 struct spdk_ftl_punit_range range; 136 /* Mode flags */ 137 unsigned int mode; 138 /* Device UUID (valid when restoring device from disk) */ 139 struct spdk_uuid uuid; 140 }; 141 142 struct spdk_ftl_attrs { 143 /* Device's UUID */ 144 struct spdk_uuid uuid; 145 /* Parallel unit range */ 146 struct spdk_ftl_punit_range range; 147 /* Number of logical blocks */ 148 uint64_t lbk_cnt; 149 /* Logical block size */ 150 size_t lbk_size; 151 /* Write buffer cache */ 152 struct spdk_bdev_desc *cache_bdev_desc; 153 /* Number of chunks per parallel unit in the underlying device (including any offline ones) */ 154 size_t num_chunks; 155 /* Number of sectors per chunk */ 156 size_t chunk_size; 157 /* Device specific configuration */ 158 struct spdk_ftl_conf conf; 159 }; 160 161 struct ftl_module_init_opts { 162 /* Thread on which to poll for ANM events */ 163 struct spdk_thread *anm_thread; 164 }; 165 166 typedef void (*spdk_ftl_fn)(void *, int); 167 typedef void (*spdk_ftl_init_fn)(struct spdk_ftl_dev *, void *, int); 168 169 /** 170 * Initialize the FTL module. 171 * 172 * \param opts module configuration 173 * \param cb callback function to call when the module is initialized 174 * \param cb_arg callback's argument 175 * 176 * \return 0 if successfully started initialization, negative values if 177 * resources could not be allocated. 178 */ 179 int spdk_ftl_module_init(const struct ftl_module_init_opts *opts, spdk_ftl_fn cb, void *cb_arg); 180 181 /** 182 * Deinitialize the FTL module. All FTL devices have to be unregistered prior to 183 * calling this function. 184 * 185 * \param cb callback function to call when the deinitialization is completed 186 * \param cb_arg callback's argument 187 * 188 * \return 0 if successfully scheduled deinitialization, negative errno 189 * otherwise. 190 */ 191 int spdk_ftl_module_fini(spdk_ftl_fn cb, void *cb_arg); 192 193 /** 194 * Initialize the FTL on given NVMe device and parallel unit range. 195 * 196 * Covers the following: 197 * - initialize and register NVMe ctrlr, 198 * - retrieve geometry and check if the device has proper configuration, 199 * - allocate buffers and resources, 200 * - initialize internal structures, 201 * - initialize internal thread(s), 202 * - restore or create L2P table. 203 * 204 * \param opts configuration for new device 205 * \param cb callback function to call when the device is created 206 * \param cb_arg callback's argument 207 * 208 * \return 0 if initialization was started successfully, negative errno otherwise. 209 */ 210 int spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *opts, spdk_ftl_init_fn cb, void *cb_arg); 211 212 /** 213 * Deinitialize and free given device. 214 * 215 * \param dev device 216 * \param cb callback function to call when the device is freed 217 * \param cb_arg callback's argument 218 * 219 * \return 0 if successfully scheduled free, negative errno otherwise. 220 */ 221 int spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_init_fn cb, void *cb_arg); 222 223 /** 224 * Initialize FTL configuration structure with default values. 225 * 226 * \param conf FTL configuration to initialize 227 */ 228 void spdk_ftl_conf_init_defaults(struct spdk_ftl_conf *conf); 229 230 /** 231 * Retrieve device’s attributes. 232 * 233 * \param dev device 234 * \param attr Attribute structure to fill 235 */ 236 void spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *attr); 237 238 /** 239 * Submits a read to the specified device. 240 * 241 * \param dev Device 242 * \param ch I/O channel 243 * \param lba Starting LBA to read the data 244 * \param lba_cnt Number of sectors to read 245 * \param iov Single IO vector or pointer to IO vector table 246 * \param iov_cnt Number of IO vectors 247 * \param cb_fn Callback function to invoke when the I/O is completed 248 * \param cb_arg Argument to pass to the callback function 249 * 250 * \return 0 if successfully submitted, negative errno otherwise. 251 */ 252 int spdk_ftl_read(struct spdk_ftl_dev *dev, struct spdk_io_channel *ch, uint64_t lba, 253 size_t lba_cnt, 254 struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 255 256 /** 257 * Submits a write to the specified device. 258 * 259 * \param dev Device 260 * \param ch I/O channel 261 * \param lba Starting LBA to write the data 262 * \param lba_cnt Number of sectors to write 263 * \param iov Single IO vector or pointer to IO vector table 264 * \param iov_cnt Number of IO vectors 265 * \param cb_fn Callback function to invoke when the I/O is completed 266 * \param cb_arg Argument to pass to the callback function 267 * 268 * \return 0 if successfully submitted, negative errno otherwise. 269 */ 270 int spdk_ftl_write(struct spdk_ftl_dev *dev, struct spdk_io_channel *ch, uint64_t lba, 271 size_t lba_cnt, 272 struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 273 274 /** 275 * Submits a flush request to the specified device. 276 * 277 * \param dev device 278 * \param cb_fn Callback function to invoke when all prior IOs have been completed 279 * \param cb_arg Argument to pass to the callback function 280 * 281 * \return 0 if successfully submitted, negative errno otherwise. 282 */ 283 int spdk_ftl_flush(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg); 284 285 #ifdef __cplusplus 286 } 287 #endif 288 289 #endif /* SPDK_FTL_H */ 290