1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #ifndef SPDK_FTL_H 7 #define SPDK_FTL_H 8 9 #include "spdk/stdinc.h" 10 #include "spdk/uuid.h" 11 #include "spdk/thread.h" 12 #include "spdk/bdev.h" 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 struct spdk_ftl_dev; 19 struct ftl_io; 20 struct spdk_jsonrpc_request; 21 22 /* Limit thresholds */ 23 enum { 24 SPDK_FTL_LIMIT_CRIT, 25 SPDK_FTL_LIMIT_HIGH, 26 SPDK_FTL_LIMIT_LOW, 27 SPDK_FTL_LIMIT_START, 28 SPDK_FTL_LIMIT_MAX 29 }; 30 31 struct ftl_stats_error { 32 uint64_t media; 33 uint64_t crc; 34 uint64_t other; 35 }; 36 37 struct ftl_stats_group { 38 uint64_t ios; 39 uint64_t blocks; 40 struct ftl_stats_error errors; 41 }; 42 43 struct ftl_stats_entry { 44 struct ftl_stats_group read; 45 struct ftl_stats_group write; 46 }; 47 48 enum ftl_stats_type { 49 FTL_STATS_TYPE_USER = 0, 50 FTL_STATS_TYPE_CMP, 51 FTL_STATS_TYPE_GC, 52 FTL_STATS_TYPE_MD_BASE, 53 FTL_STATS_TYPE_MD_NV_CACHE, 54 FTL_STATS_TYPE_L2P, 55 FTL_STATS_TYPE_MAX, 56 }; 57 58 struct ftl_stats { 59 /* Number of times write limits were triggered by FTL writers 60 * (gc and compaction) dependent on number of free bands. GC starts at 61 * SPDK_FTL_LIMIT_START level, while at SPDK_FTL_LIMIT_CRIT compaction stops 62 * and only GC is allowed to work. 63 */ 64 uint64_t limits[SPDK_FTL_LIMIT_MAX]; 65 66 /* Total number of blocks with IO to the underlying devices 67 * 1. nv cache read/write 68 * 2. base bdev read/write 69 */ 70 uint64_t io_activity_total; 71 72 struct ftl_stats_entry entries[FTL_STATS_TYPE_MAX]; 73 }; 74 75 typedef void (*spdk_ftl_stats_fn)(struct ftl_stats *stats, void *cb_arg); 76 77 /* 78 * FTL configuration. 79 * 80 * NOTE: Do not change the layout of this structure. Only add new fields at the end. 81 */ 82 struct spdk_ftl_conf { 83 /* Device's name */ 84 char *name; 85 86 /* Device UUID (valid when restoring device from disk) */ 87 struct spdk_uuid uuid; 88 89 /* Percentage of base device blocks not exposed to the user */ 90 uint64_t overprovisioning; 91 92 /* l2p cache size that could reside in DRAM (in MiB) */ 93 size_t l2p_dram_limit; 94 95 /* Core mask - core thread plus additional relocation threads */ 96 char *core_mask; 97 98 /* IO pool size per user thread */ 99 size_t user_io_pool_size; 100 101 /* User writes limits */ 102 size_t limits[SPDK_FTL_LIMIT_MAX]; 103 104 /* FTL startup mode mask, see spdk_ftl_mode enum for possible values */ 105 uint32_t mode; 106 107 struct { 108 /* Start compaction when full chunks exceed given % of entire chunks */ 109 uint32_t chunk_compaction_threshold; 110 111 /* Percentage of chunks to maintain free */ 112 uint32_t chunk_free_target; 113 } nv_cache; 114 115 /* Hole at bytes 0x60 - 0x67. */ 116 uint8_t reserved[4]; 117 118 /* Name of base block device (zoned or non-zoned) */ 119 char *base_bdev; 120 121 /* Name of cache block device (must support extended metadata) */ 122 char *cache_bdev; 123 124 /* Enable fast shutdown path */ 125 bool fast_shutdown; 126 127 /* Hole at bytes 0x79 - 0x7f. */ 128 uint8_t reserved2[7]; 129 130 /* 131 * The size of spdk_ftl_conf according to the caller of this library is used for ABI 132 * compatibility. The library uses this field to know how many fields in this 133 * structure are valid. And the library will populate any remaining fields with default values. 134 */ 135 size_t conf_size; 136 } __attribute__((packed)); 137 SPDK_STATIC_ASSERT(sizeof(struct spdk_ftl_conf) == 136, "Incorrect size"); 138 139 enum spdk_ftl_mode { 140 /* Create new device */ 141 SPDK_FTL_MODE_CREATE = (1 << 0), 142 }; 143 144 /* 145 * FTL device attributes. 146 * 147 * NOTE: Do not change the layout of this structure. Only add new fields at the end. 148 */ 149 struct spdk_ftl_attrs { 150 /* Number of logical blocks */ 151 uint64_t num_blocks; 152 /* Logical block size */ 153 uint64_t block_size; 154 /* Optimal IO size - bdev layer will split requests over this size */ 155 uint64_t optimum_io_size; 156 }; 157 158 typedef void (*spdk_ftl_fn)(void *cb_arg, int status); 159 typedef void (*spdk_ftl_init_fn)(struct spdk_ftl_dev *dev, void *cb_arg, int status); 160 161 /** 162 * Initializes the FTL library. 163 * 164 * @return 0 on success, negative errno otherwise. 165 */ 166 int spdk_ftl_init(void); 167 168 /** 169 * Deinitializes the FTL library. 170 */ 171 void spdk_ftl_fini(void); 172 173 /** 174 * Initialize the FTL on the given pair of bdevs - base and cache bdev. 175 * Upon receiving a successful completion callback user is free to use I/O calls. 176 * 177 * \param conf configuration for new device 178 * \param cb callback function to call when the device is created 179 * \param cb_arg callback's argument 180 * 181 * \return 0 if initialization was started successfully, negative errno otherwise. 182 */ 183 int spdk_ftl_dev_init(const struct spdk_ftl_conf *conf, spdk_ftl_init_fn cb, void *cb_arg); 184 185 /** 186 * Deinitialize and free given device. 187 * 188 * \param dev device 189 * \param cb callback function to call when the device is freed 190 * \param cb_arg callback's argument 191 * 192 * \return 0 if deinitialization was started successfully, negative errno otherwise. 193 */ 194 int spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_fn cb, void *cb_arg); 195 196 /** 197 * Retrieve device’s attributes. 198 * 199 * \param dev device 200 * \param attr Attribute structure to fill 201 * \param attrs_size Must be set to sizeof(struct spdk_ftl_attrs) 202 */ 203 void spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *attr, 204 size_t attrs_size); 205 206 /** 207 * Retrieve device’s configuration. 208 * 209 * \param dev device 210 * \param conf FTL configuration structure to fill 211 * \param conf_size Must be set to sizeof(struct spdk_ftl_conf) 212 */ 213 void spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf, 214 size_t conf_size); 215 216 /** 217 * Obtain an I/O channel for the device. 218 * 219 * \param dev device 220 * 221 * \return A handle to the I/O channel or NULL on failure. 222 */ 223 struct spdk_io_channel *spdk_ftl_get_io_channel(struct spdk_ftl_dev *dev); 224 225 /** 226 * Make a deep copy of an FTL configuration structure 227 * 228 * \param dst The destination FTL configuration 229 * \param src The source FTL configuration 230 */ 231 int spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src); 232 233 /** 234 * Release the FTL configuration resources. This does not free the structure itself. 235 * 236 * \param conf FTL configuration to deinitialize 237 */ 238 void spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf); 239 240 /** 241 * Initialize FTL configuration structure with default values. 242 * 243 * \param conf FTL configuration to initialize 244 * \param conf_size Must be set to sizeof(struct spdk_ftl_conf) 245 */ 246 void spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf, size_t conf_size); 247 248 /** 249 * Submits a read to the specified device. 250 * 251 * \param dev Device 252 * \param io Allocated ftl_io 253 * \param ch I/O channel 254 * \param lba Starting LBA to read the data 255 * \param lba_cnt Number of sectors to read 256 * \param iov Single IO vector or pointer to IO vector table 257 * \param iov_cnt Number of IO vectors 258 * \param cb_fn Callback function to invoke when the I/O is completed 259 * \param cb_arg Argument to pass to the callback function 260 * 261 * \return 0 if successfully submitted, negative errno otherwise. 262 */ 263 int spdk_ftl_readv(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch, 264 uint64_t lba, uint64_t lba_cnt, 265 struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 266 267 /** 268 * Submits a write to the specified device. 269 * 270 * \param dev Device 271 * \param io Allocated ftl_io 272 * \param ch I/O channel 273 * \param lba Starting LBA to write the data 274 * \param lba_cnt Number of sectors to write 275 * \param iov Single IO vector or pointer to IO vector table 276 * \param iov_cnt Number of IO vectors 277 * \param cb_fn Callback function to invoke when the I/O is completed 278 * \param cb_arg Argument to pass to the callback function 279 * 280 * \return 0 if successfully submitted, negative errno otherwise. 281 */ 282 int spdk_ftl_writev(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch, 283 uint64_t lba, uint64_t lba_cnt, 284 struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 285 286 /** 287 * Submits a unmap to the specified device. 288 * 289 * \param dev Device 290 * \param io Allocated ftl_io 291 * \param ch I/O channel 292 * \param lba Starting LBA to write the data 293 * \param lba_cnt Number of blocks to unmap 294 * \param cb_fn Callback function to invoke when the I/O is completed 295 * \param cb_arg Argument to pass to the callback function 296 * 297 * \return 0 if successfully submitted, negative errno otherwise. 298 */ 299 int spdk_ftl_unmap(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch, 300 uint64_t lba, uint64_t lba_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 301 302 /** 303 * Returns the size of ftl_io struct that needs to be passed to spdk_ftl_read/write 304 * 305 * \return The size of struct 306 */ 307 size_t spdk_ftl_io_size(void); 308 309 /** 310 * Enable fast shutdown. 311 * 312 * During fast shutdown FTL will keep the necessary metadata in shared memory instead 313 * of serializing it to storage. This allows for shorter downtime during upgrade process. 314 */ 315 void spdk_ftl_dev_set_fast_shutdown(struct spdk_ftl_dev *dev, bool fast_shutdown); 316 317 /* 318 * Returns current FTL I/O statistics. 319 * 320 * \param dev Device 321 * \param stats Allocated ftl_stats 322 * \param cb_fn Callback function to invoke when the call is completed 323 * \param cb_arg Argument to pass to the callback function 324 * 325 * \return 0 if successfully submitted, negative errno otherwise. 326 */ 327 int spdk_ftl_get_stats(struct spdk_ftl_dev *dev, struct ftl_stats *stats, spdk_ftl_stats_fn cb_fn, 328 void *cb_arg); 329 330 /** 331 * Gets properties of the specified device. 332 * 333 * \param dev FTL device 334 * \param request JSON RPC request where the properties will be stored 335 * \param cb_fn Callback function to invoke when the operation is completed 336 * \param cb_arg Argument to pass to the callback function 337 * 338 * \return 0 if successfully submitted, negative errno otherwise. 339 */ 340 int spdk_ftl_get_properties(struct spdk_ftl_dev *dev, struct spdk_jsonrpc_request *request, 341 spdk_ftl_fn cb_fn, void *cb_arg); 342 343 #ifdef __cplusplus 344 } 345 #endif 346 347 #endif /* SPDK_FTL_H */ 348