1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #ifndef FTL_NV_CACHE_H 7 #define FTL_NV_CACHE_H 8 9 #include "spdk/stdinc.h" 10 #include "spdk/crc32.h" 11 12 #include "ftl_io.h" 13 #include "ftl_utils.h" 14 15 #define FTL_NVC_VERSION_0 0 16 #define FTL_NVC_VERSION_1 1 17 18 #define FTL_NVC_VERSION_CURRENT FTL_NVC_VERSION_1 19 20 struct ftl_nvcache_restore; 21 typedef void (*ftl_nv_cache_restore_fn)(struct ftl_nvcache_restore *, int, void *cb_arg); 22 23 enum ftl_chunk_state { 24 FTL_CHUNK_STATE_FREE, 25 FTL_CHUNK_STATE_OPEN, 26 FTL_CHUNK_STATE_CLOSED, 27 FTL_CHUNK_STATE_MAX 28 }; 29 30 struct ftl_nv_cache_chunk_md { 31 /* Current lba to write */ 32 uint32_t write_pointer; 33 34 /* Number of blocks written */ 35 uint32_t blocks_written; 36 37 /* Number of skipped block (case when IO size is greater than blocks left in chunk) */ 38 uint32_t blocks_skipped; 39 40 /* Next block to be compacted */ 41 uint32_t read_pointer; 42 43 /* Number of compacted (both valid and invalid) blocks */ 44 uint32_t blocks_compacted; 45 46 /* Chunk state */ 47 enum ftl_chunk_state state; 48 49 /* CRC32 checksum of the associated P2L map when chunk is in closed state */ 50 uint32_t p2l_map_checksum; 51 } __attribute__((aligned(FTL_BLOCK_SIZE))); 52 53 #define FTL_NV_CACHE_CHUNK_MD_SIZE sizeof(struct ftl_nv_cache_chunk_md) 54 SPDK_STATIC_ASSERT(FTL_NV_CACHE_CHUNK_MD_SIZE == FTL_BLOCK_SIZE, 55 "FTL NV Chunk metadata size is invalid"); 56 57 struct ftl_nv_cache_chunk { 58 struct ftl_nv_cache *nv_cache; 59 60 struct ftl_nv_cache_chunk_md *md; 61 62 /* Offset from start lba of the cache */ 63 uint64_t offset; 64 65 /* P2L map */ 66 struct ftl_p2l_map p2l_map; 67 68 /* Metadata request */ 69 struct ftl_basic_rq metadata_rq; 70 71 TAILQ_ENTRY(ftl_nv_cache_chunk) entry; 72 73 /* This flag is used to indicate chunk is used in recovery */ 74 bool recovery; 75 76 /* For writing metadata */ 77 struct ftl_md_io_entry_ctx md_persist_entry_ctx; 78 }; 79 80 struct ftl_nv_cache { 81 /* Flag indicating halt request */ 82 bool halt; 83 84 /* Write buffer cache bdev */ 85 struct spdk_bdev_desc *bdev_desc; 86 87 /* Persistent cache IO channel */ 88 struct spdk_io_channel *cache_ioch; 89 90 /* Metadata pool */ 91 struct ftl_mempool *md_pool; 92 93 /* P2L map memory pool */ 94 struct ftl_mempool *p2l_pool; 95 96 /* Chunk md memory pool */ 97 struct ftl_mempool *chunk_md_pool; 98 99 /* Block Metadata size */ 100 uint64_t md_size; 101 102 /* NV cache metadata object handle */ 103 struct ftl_md *md; 104 105 /* Number of blocks in chunk */ 106 uint64_t chunk_blocks; 107 108 /* Number of chunks */ 109 uint64_t chunk_count; 110 111 /* Current processed chunk */ 112 struct ftl_nv_cache_chunk *chunk_current; 113 114 /* Free chunks list */ 115 TAILQ_HEAD(, ftl_nv_cache_chunk) chunk_free_list; 116 uint64_t chunk_free_count; 117 118 /* Open chunks list */ 119 TAILQ_HEAD(, ftl_nv_cache_chunk) chunk_open_list; 120 uint64_t chunk_open_count; 121 122 /* Full chunks list */ 123 TAILQ_HEAD(, ftl_nv_cache_chunk) chunk_full_list; 124 uint64_t chunk_full_count; 125 126 struct ftl_nv_cache_chunk *chunks; 127 }; 128 129 int ftl_nv_cache_init(struct spdk_ftl_dev *dev); 130 void ftl_nv_cache_deinit(struct spdk_ftl_dev *dev); 131 void ftl_nv_cache_fill_md(struct ftl_io *io); 132 int ftl_nv_cache_read(struct ftl_io *io, ftl_addr addr, uint32_t num_blocks, 133 spdk_bdev_io_completion_cb cb, void *cb_arg); 134 bool ftl_nv_cache_full(struct ftl_nv_cache *nv_cache); 135 void ftl_nv_cache_process(struct spdk_ftl_dev *dev); 136 137 void ftl_nv_cache_halt(struct ftl_nv_cache *nv_cache); 138 139 int ftl_nv_cache_chunks_busy(struct ftl_nv_cache *nv_cache); 140 141 static inline void 142 ftl_nv_cache_resume(struct ftl_nv_cache *nv_cache) 143 { 144 nv_cache->halt = false; 145 } 146 147 bool ftl_nv_cache_is_halted(struct ftl_nv_cache *nv_cache); 148 149 size_t ftl_nv_cache_chunk_tail_md_num_blocks(const struct ftl_nv_cache *nv_cache); 150 151 uint64_t chunk_tail_md_offset(struct ftl_nv_cache *nv_cache); 152 153 typedef int (*ftl_chunk_md_cb)(struct ftl_nv_cache_chunk *chunk, void *cntx); 154 155 #endif /* FTL_NV_CACHE_H */ 156