xref: /spdk/lib/ftl/ftl_nv_cache.h (revision cdb0726b95631d46eaf4f2e39ddb6533f150fd27)
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