1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #ifndef FTL_CORE_H 7 #define FTL_CORE_H 8 9 #include "spdk/stdinc.h" 10 #include "spdk/uuid.h" 11 #include "spdk/thread.h" 12 #include "spdk/util.h" 13 #include "spdk/likely.h" 14 #include "spdk/queue.h" 15 #include "spdk/ftl.h" 16 #include "spdk/bdev.h" 17 #include "spdk/bdev_zone.h" 18 19 #include "ftl_internal.h" 20 #include "ftl_io.h" 21 #include "ftl_layout.h" 22 #include "ftl_sb.h" 23 #include "utils/ftl_log.h" 24 25 /* When using VSS on nvcache, FTL sometimes doesn't require the contents of metadata. 26 * Some devices have bugs when sending a NULL pointer as part of metadata when namespace 27 * is formatted with VSS. This buffer is passed to such calls to avoid the bug. */ 28 #define FTL_ZERO_BUFFER_SIZE 0x100000 29 extern void *g_ftl_write_buf; 30 extern void *g_ftl_read_buf; 31 32 struct spdk_ftl_dev { 33 /* Configuration */ 34 struct spdk_ftl_conf conf; 35 36 /* FTL device layout */ 37 struct ftl_layout layout; 38 39 /* FTL superblock */ 40 struct ftl_superblock *sb; 41 42 /* Queue of registered IO channels */ 43 TAILQ_HEAD(, ftl_io_channel) ioch_queue; 44 45 /* Underlying device */ 46 struct spdk_bdev_desc *base_bdev_desc; 47 48 /* Cache device */ 49 struct spdk_bdev_desc *cache_bdev_desc; 50 51 /* Cache VSS metadata size */ 52 uint64_t cache_md_size; 53 54 /* Cached properties of the underlying device */ 55 uint64_t num_blocks_in_band; 56 uint64_t num_zones_in_band; 57 uint64_t num_blocks_in_zone; 58 bool is_zoned; 59 60 /* Indicates the device is fully initialized */ 61 bool initialized; 62 63 /* Indicates the device is about to be stopped */ 64 bool halt; 65 66 /* Indicates if the device is registered as an IO device */ 67 bool io_device_registered; 68 69 /* Management process to be continued after IO device unregistration completes */ 70 struct ftl_mngt_process *unregister_process; 71 72 /* counters for poller busy, include 73 1. nv cache read/write 74 2. metadata read/write 75 3. base bdev read/write */ 76 uint64_t io_activity_total; 77 78 /* Number of operational bands */ 79 uint64_t num_bands; 80 81 /* Number of free bands */ 82 uint64_t num_free; 83 84 /* Size of the l2p table */ 85 uint64_t num_lbas; 86 87 /* Metadata size */ 88 uint64_t md_size; 89 90 /* Transfer unit size */ 91 uint64_t xfer_size; 92 93 /* Inflight IO operations */ 94 uint32_t num_inflight; 95 96 /* Thread on which the poller is running */ 97 struct spdk_thread *core_thread; 98 99 /* IO channel to the FTL device, used for internal management operations 100 * consuming FTL's external API 101 */ 102 struct spdk_io_channel *ioch; 103 104 /* Underlying device IO channel */ 105 struct spdk_io_channel *base_ioch; 106 107 /* Cache IO channel */ 108 struct spdk_io_channel *cache_ioch; 109 110 /* Poller */ 111 struct spdk_poller *core_poller; 112 113 /* Read submission queue */ 114 TAILQ_HEAD(, ftl_io) rd_sq; 115 116 /* Write submission queue */ 117 TAILQ_HEAD(, ftl_io) wr_sq; 118 }; 119 120 int ftl_core_poller(void *ctx); 121 122 int ftl_io_channel_poll(void *arg); 123 124 struct ftl_io_channel *ftl_io_channel_get_ctx(struct spdk_io_channel *ioch); 125 126 static inline uint64_t 127 ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev) 128 { 129 return dev->num_blocks_in_band; 130 } 131 132 static inline size_t 133 ftl_get_num_zones_in_band(const struct spdk_ftl_dev *dev) 134 { 135 return dev->num_zones_in_band; 136 } 137 138 static inline size_t 139 ftl_get_num_blocks_in_zone(const struct spdk_ftl_dev *dev) 140 { 141 return dev->num_blocks_in_zone; 142 } 143 144 static inline uint32_t 145 ftl_get_write_unit_size(struct spdk_bdev *bdev) 146 { 147 if (spdk_bdev_is_zoned(bdev)) { 148 return spdk_bdev_get_write_unit_size(bdev); 149 } 150 151 /* TODO: this should be passed via input parameter */ 152 return 32; 153 } 154 155 static inline struct spdk_thread * 156 ftl_get_core_thread(const struct spdk_ftl_dev *dev) 157 { 158 return dev->core_thread; 159 } 160 161 static inline size_t 162 ftl_get_num_bands(const struct spdk_ftl_dev *dev) 163 { 164 return dev->num_bands; 165 } 166 167 static inline size_t 168 ftl_get_num_zones(const struct spdk_ftl_dev *dev) 169 { 170 return ftl_get_num_bands(dev) * ftl_get_num_zones_in_band(dev); 171 } 172 173 static inline bool 174 ftl_check_core_thread(const struct spdk_ftl_dev *dev) 175 { 176 return dev->core_thread == spdk_get_thread(); 177 } 178 179 #endif /* FTL_CORE_H */ 180