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/uuid.h" 39 #include "spdk/thread.h" 40 #include "spdk/bdev.h" 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 struct spdk_ftl_dev; 47 48 /* Limit thresholds */ 49 enum { 50 SPDK_FTL_LIMIT_CRIT, 51 SPDK_FTL_LIMIT_HIGH, 52 SPDK_FTL_LIMIT_LOW, 53 SPDK_FTL_LIMIT_START, 54 SPDK_FTL_LIMIT_MAX 55 }; 56 57 struct spdk_ftl_limit { 58 /* Threshold from which the limiting starts */ 59 size_t thld; 60 61 /* Limit percentage */ 62 size_t limit; 63 }; 64 65 struct spdk_ftl_conf { 66 /* Number of reserved addresses not exposed to the user */ 67 size_t lba_rsvd; 68 69 /* Size of the per-io_channel write buffer */ 70 size_t write_buffer_size; 71 72 /* Threshold for opening new band */ 73 size_t band_thld; 74 75 /* Maximum IO depth per band relocate */ 76 size_t max_reloc_qdepth; 77 78 /* Maximum active band relocates */ 79 size_t max_active_relocs; 80 81 /* IO pool size per user thread */ 82 size_t user_io_pool_size; 83 84 /* Lowest percentage of invalid blocks for a band to be defragged */ 85 size_t invalid_thld; 86 87 /* User writes limits */ 88 struct spdk_ftl_limit limits[SPDK_FTL_LIMIT_MAX]; 89 90 /* Allow for partial recovery from open bands instead of returning error */ 91 bool allow_open_bands; 92 93 /* Use append instead of write */ 94 bool use_append; 95 96 /* Maximum supported number of IO channels */ 97 uint32_t max_io_channels; 98 99 struct { 100 /* Maximum number of concurrent requests */ 101 size_t max_request_cnt; 102 /* Maximum number of blocks per one request */ 103 size_t max_request_size; 104 } nv_cache; 105 106 /* Create l2p table on l2p_path persistent memory file or device instead of in DRAM */ 107 const char *l2p_path; 108 }; 109 110 enum spdk_ftl_mode { 111 /* Create new device */ 112 SPDK_FTL_MODE_CREATE = (1 << 0), 113 }; 114 115 struct spdk_ftl_dev_init_opts { 116 /* Underlying device */ 117 const char *base_bdev; 118 /* Write buffer cache */ 119 const char *cache_bdev; 120 121 /* Thread responsible for core tasks execution */ 122 struct spdk_thread *core_thread; 123 124 /* Device's config */ 125 const struct spdk_ftl_conf *conf; 126 /* Device's name */ 127 const char *name; 128 /* Mode flags */ 129 unsigned int mode; 130 /* Device UUID (valid when restoring device from disk) */ 131 struct spdk_uuid uuid; 132 }; 133 134 struct spdk_ftl_attrs { 135 /* Device's UUID */ 136 struct spdk_uuid uuid; 137 /* Number of logical blocks */ 138 uint64_t num_blocks; 139 /* Logical block size */ 140 size_t block_size; 141 /* Underlying device */ 142 const char *base_bdev; 143 /* Write buffer cache */ 144 const char *cache_bdev; 145 /* Number of zones per parallel unit in the underlying device (including any offline ones) */ 146 size_t num_zones; 147 /* Number of logical blocks per zone */ 148 size_t zone_size; 149 /* Device specific configuration */ 150 struct spdk_ftl_conf conf; 151 }; 152 153 typedef void (*spdk_ftl_fn)(void *, int); 154 typedef void (*spdk_ftl_init_fn)(struct spdk_ftl_dev *, void *, int); 155 156 /** 157 * Initialize the FTL on given NVMe device and parallel unit range. 158 * 159 * Covers the following: 160 * - retrieve zone device information, 161 * - allocate buffers and resources, 162 * - initialize internal structures, 163 * - initialize internal thread(s), 164 * - restore or create L2P table. 165 * 166 * \param opts configuration for new device 167 * \param cb callback function to call when the device is created 168 * \param cb_arg callback's argument 169 * 170 * \return 0 if initialization was started successfully, negative errno otherwise. 171 */ 172 int spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *opts, spdk_ftl_init_fn cb, void *cb_arg); 173 174 /** 175 * Deinitialize and free given device. 176 * 177 * \param dev device 178 * \param cb callback function to call when the device is freed 179 * \param cb_arg callback's argument 180 * 181 * \return 0 if successfully scheduled free, negative errno otherwise. 182 */ 183 int spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_init_fn cb, void *cb_arg); 184 185 /** 186 * Initialize FTL configuration structure with default values. 187 * 188 * \param conf FTL configuration to initialize 189 */ 190 void spdk_ftl_conf_init_defaults(struct spdk_ftl_conf *conf); 191 192 /** 193 * Retrieve device’s attributes. 194 * 195 * \param dev device 196 * \param attr Attribute structure to fill 197 */ 198 void spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *attr); 199 200 /** 201 * Submits a read to the specified device. 202 * 203 * \param dev Device 204 * \param ch I/O channel 205 * \param lba Starting LBA to read the data 206 * \param lba_cnt Number of sectors to read 207 * \param iov Single IO vector or pointer to IO vector table 208 * \param iov_cnt Number of IO vectors 209 * \param cb_fn Callback function to invoke when the I/O is completed 210 * \param cb_arg Argument to pass to the callback function 211 * 212 * \return 0 if successfully submitted, negative errno otherwise. 213 */ 214 int spdk_ftl_read(struct spdk_ftl_dev *dev, struct spdk_io_channel *ch, uint64_t lba, 215 size_t lba_cnt, 216 struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 217 218 /** 219 * Submits a write to the specified device. 220 * 221 * \param dev Device 222 * \param ch I/O channel 223 * \param lba Starting LBA to write the data 224 * \param lba_cnt Number of sectors to write 225 * \param iov Single IO vector or pointer to IO vector table 226 * \param iov_cnt Number of IO vectors 227 * \param cb_fn Callback function to invoke when the I/O is completed 228 * \param cb_arg Argument to pass to the callback function 229 * 230 * \return 0 if successfully submitted, negative errno otherwise. 231 */ 232 int spdk_ftl_write(struct spdk_ftl_dev *dev, struct spdk_io_channel *ch, uint64_t lba, 233 size_t lba_cnt, 234 struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 235 236 /** 237 * Submits a flush request to the specified device. 238 * 239 * \param dev device 240 * \param cb_fn Callback function to invoke when all prior IOs have been completed 241 * \param cb_arg Argument to pass to the callback function 242 * 243 * \return 0 if successfully submitted, negative errno otherwise. 244 */ 245 int spdk_ftl_flush(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg); 246 247 #ifdef __cplusplus 248 } 249 #endif 250 251 #endif /* SPDK_FTL_H */ 252