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 /* 116 * This flags indicates that FTL during shutdown should execute all 117 * actions which are needed for upgrade to a new version 118 */ 119 bool prep_upgrade_on_shutdown; 120 121 /* In verbose mode, user is able to get access to additional advanced FTL properties. 122 * 123 * Advanced properties currently include entries, which will result in printing large amount of data 124 * (e.g. state of all bands, or chunks); or allow for receiving internal state of FTL (e.g. bands currently 125 * used for garbage collection) - live data which may be useful for profiling, or debugging. 126 */ 127 bool verbose_mode; 128 129 /* Hole at bytes 0x66 - 0x67. */ 130 uint8_t reserved[2]; 131 132 /* Name of base block device (zoned or non-zoned) */ 133 char *base_bdev; 134 135 /* Name of cache block device (must support extended metadata) */ 136 char *cache_bdev; 137 138 /* Enable fast shutdown path */ 139 bool fast_shutdown; 140 141 /* Hole at bytes 0x79 - 0x7f. */ 142 uint8_t reserved2[7]; 143 144 /* 145 * The size of spdk_ftl_conf according to the caller of this library is used for ABI 146 * compatibility. The library uses this field to know how many fields in this 147 * structure are valid. And the library will populate any remaining fields with default values. 148 */ 149 size_t conf_size; 150 } __attribute__((packed)); 151 SPDK_STATIC_ASSERT(sizeof(struct spdk_ftl_conf) == 136, "Incorrect size"); 152 153 enum spdk_ftl_mode { 154 /* Create new device */ 155 SPDK_FTL_MODE_CREATE = (1 << 0), 156 }; 157 158 /* 159 * FTL device attributes. 160 * 161 * NOTE: Do not change the layout of this structure. Only add new fields at the end. 162 */ 163 struct spdk_ftl_attrs { 164 /* Number of logical blocks */ 165 uint64_t num_blocks; 166 /* Logical block size */ 167 uint64_t block_size; 168 /* Optimal IO size - bdev layer will split requests over this size */ 169 uint64_t optimum_io_size; 170 }; 171 172 typedef void (*spdk_ftl_fn)(void *cb_arg, int status); 173 typedef void (*spdk_ftl_init_fn)(struct spdk_ftl_dev *dev, void *cb_arg, int status); 174 175 /** 176 * Initializes the FTL library. 177 * 178 * @return 0 on success, negative errno otherwise. 179 */ 180 int spdk_ftl_init(void); 181 182 /** 183 * Deinitializes the FTL library. 184 */ 185 void spdk_ftl_fini(void); 186 187 /** 188 * Initialize the FTL on the given pair of bdevs - base and cache bdev. 189 * Upon receiving a successful completion callback user is free to use I/O calls. 190 * 191 * \param conf configuration for new device 192 * \param cb callback function to call when the device is created 193 * \param cb_arg callback's argument 194 * 195 * \return 0 if initialization was started successfully, negative errno otherwise. 196 */ 197 int spdk_ftl_dev_init(const struct spdk_ftl_conf *conf, spdk_ftl_init_fn cb, void *cb_arg); 198 199 /** 200 * Deinitialize and free given device. 201 * 202 * \param dev device 203 * \param cb callback function to call when the device is freed 204 * \param cb_arg callback's argument 205 * 206 * \return 0 if deinitialization was started successfully, negative errno otherwise. 207 */ 208 int spdk_ftl_dev_free(struct spdk_ftl_dev *dev, spdk_ftl_fn cb, void *cb_arg); 209 210 /** 211 * Retrieve device’s attributes. 212 * 213 * \param dev device 214 * \param attr Attribute structure to fill 215 * \param attrs_size Must be set to sizeof(struct spdk_ftl_attrs) 216 */ 217 void spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *attr, 218 size_t attrs_size); 219 220 /** 221 * Retrieve device’s configuration. 222 * 223 * \param dev device 224 * \param conf FTL configuration structure to fill 225 * \param conf_size Must be set to sizeof(struct spdk_ftl_conf) 226 */ 227 void spdk_ftl_dev_get_conf(const struct spdk_ftl_dev *dev, struct spdk_ftl_conf *conf, 228 size_t conf_size); 229 230 /** 231 * Obtain an I/O channel for the device. 232 * 233 * \param dev device 234 * 235 * \return A handle to the I/O channel or NULL on failure. 236 */ 237 struct spdk_io_channel *spdk_ftl_get_io_channel(struct spdk_ftl_dev *dev); 238 239 /** 240 * Make a deep copy of an FTL configuration structure 241 * 242 * \param dst The destination FTL configuration 243 * \param src The source FTL configuration 244 */ 245 int spdk_ftl_conf_copy(struct spdk_ftl_conf *dst, const struct spdk_ftl_conf *src); 246 247 /** 248 * Release the FTL configuration resources. This does not free the structure itself. 249 * 250 * \param conf FTL configuration to deinitialize 251 */ 252 void spdk_ftl_conf_deinit(struct spdk_ftl_conf *conf); 253 254 /** 255 * Initialize FTL configuration structure with default values. 256 * 257 * \param conf FTL configuration to initialize 258 * \param conf_size Must be set to sizeof(struct spdk_ftl_conf) 259 */ 260 void spdk_ftl_get_default_conf(struct spdk_ftl_conf *conf, size_t conf_size); 261 262 /** 263 * Submits a read to the specified device. 264 * 265 * \param dev Device 266 * \param io Allocated ftl_io 267 * \param ch I/O channel 268 * \param lba Starting LBA to read the data 269 * \param lba_cnt Number of sectors to read 270 * \param iov Single IO vector or pointer to IO vector table 271 * \param iov_cnt Number of IO vectors 272 * \param cb_fn Callback function to invoke when the I/O is completed 273 * \param cb_arg Argument to pass to the callback function 274 * 275 * \return 0 if successfully submitted, negative errno otherwise. 276 */ 277 int spdk_ftl_readv(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch, 278 uint64_t lba, uint64_t lba_cnt, 279 struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 280 281 /** 282 * Submits a write to the specified device. 283 * 284 * \param dev Device 285 * \param io Allocated ftl_io 286 * \param ch I/O channel 287 * \param lba Starting LBA to write the data 288 * \param lba_cnt Number of sectors to write 289 * \param iov Single IO vector or pointer to IO vector table 290 * \param iov_cnt Number of IO vectors 291 * \param cb_fn Callback function to invoke when the I/O is completed 292 * \param cb_arg Argument to pass to the callback function 293 * 294 * \return 0 if successfully submitted, negative errno otherwise. 295 */ 296 int spdk_ftl_writev(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch, 297 uint64_t lba, uint64_t lba_cnt, 298 struct iovec *iov, size_t iov_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 299 300 /** 301 * Submits a unmap to the specified device. 302 * 303 * \param dev Device 304 * \param io Allocated ftl_io 305 * \param ch I/O channel 306 * \param lba Starting LBA to write the data 307 * \param lba_cnt Number of blocks to unmap 308 * \param cb_fn Callback function to invoke when the I/O is completed 309 * \param cb_arg Argument to pass to the callback function 310 * 311 * \return 0 if successfully submitted, negative errno otherwise. 312 */ 313 int spdk_ftl_unmap(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_channel *ch, 314 uint64_t lba, uint64_t lba_cnt, spdk_ftl_fn cb_fn, void *cb_arg); 315 316 /** 317 * Returns the size of ftl_io struct that needs to be passed to spdk_ftl_read/write 318 * 319 * \return The size of struct 320 */ 321 size_t spdk_ftl_io_size(void); 322 323 /** 324 * Enable fast shutdown. 325 * 326 * During fast shutdown FTL will keep the necessary metadata in shared memory instead 327 * of serializing it to storage. This allows for shorter downtime during upgrade process. 328 */ 329 void spdk_ftl_dev_set_fast_shutdown(struct spdk_ftl_dev *dev, bool fast_shutdown); 330 331 /* 332 * Returns current FTL I/O statistics. 333 * 334 * \param dev Device 335 * \param stats Allocated ftl_stats 336 * \param cb_fn Callback function to invoke when the call is completed 337 * \param cb_arg Argument to pass to the callback function 338 * 339 * \return 0 if successfully submitted, negative errno otherwise. 340 */ 341 int spdk_ftl_get_stats(struct spdk_ftl_dev *dev, struct ftl_stats *stats, spdk_ftl_stats_fn cb_fn, 342 void *cb_arg); 343 344 /** 345 * Gets properties of the specified device. 346 * 347 * \param dev FTL device 348 * \param request JSON RPC request where the properties will be stored 349 * \param cb_fn Callback function to invoke when the operation is completed 350 * \param cb_arg Argument to pass to the callback function 351 * 352 * \return 0 if successfully submitted, negative errno otherwise. 353 */ 354 int spdk_ftl_get_properties(struct spdk_ftl_dev *dev, struct spdk_jsonrpc_request *request, 355 spdk_ftl_fn cb_fn, void *cb_arg); 356 357 /** 358 * Sets the property of the specified device. 359 * 360 * \param dev FTL device 361 * \param property The property name to be modified 362 * \param value The new value to property 363 * \param value_size The size of the value buffer 364 * \param cb_fn Callback function to invoke when the operation is completed 365 * \param cb_arg Argument to pass to the callback function 366 * 367 * \return 0 if successfully submitted, negative errno otherwise. 368 */ 369 int spdk_ftl_set_property(struct spdk_ftl_dev *dev, const char *property, const char *value, 370 size_t value_size, spdk_ftl_fn cb_fn, void *cb_arg); 371 372 #ifdef __cplusplus 373 } 374 #endif 375 376 #endif /* SPDK_FTL_H */ 377