xref: /spdk/lib/ftl/ftl_l2p_cache.c (revision b02581a89058ebaebe03bd0e16e3b58adfe406c1)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2022 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/stdinc.h"
7 #include "spdk/cpuset.h"
8 #include "spdk/queue.h"
9 #include "spdk/thread.h"
10 #include "spdk/event.h"
11 #include "spdk/ftl.h"
12 #include "spdk/conf.h"
13 #include "spdk/env.h"
14 #include "spdk/util.h"
15 
16 #include "ftl_core.h"
17 #include "ftl_l2p_cache.h"
18 #include "ftl_layout.h"
19 #include "ftl_nv_cache_io.h"
20 #include "mngt/ftl_mngt_steps.h"
21 #include "utils/ftl_defs.h"
22 #include "utils/ftl_addr_utils.h"
23 
24 struct ftl_l2p_cache_page_io_ctx {
25 	struct ftl_l2p_cache *cache;
26 	uint64_t updates;
27 	spdk_bdev_io_completion_cb cb;
28 	struct spdk_bdev_io_wait_entry bdev_io_wait;
29 };
30 
31 enum ftl_l2p_page_state {
32 	L2P_CACHE_PAGE_INIT,		/* Page in memory not initialized from disk page */
33 	L2P_CACHE_PAGE_READY,		/* Page initialized from disk */
34 	L2P_CACHE_PAGE_FLUSHING,	/* Page is being flushed to disk and removed from memory */
35 	L2P_CACHE_PAGE_PERSISTING,	/* Page is being flushed to disk and not removed from memory */
36 	L2P_CACHE_PAGE_CLEARING,	/* Page is being initialized with INVALID addresses */
37 	L2P_CACHE_PAGE_CORRUPTED	/* Page corrupted */
38 };
39 
40 struct ftl_l2p_page {
41 	uint64_t updates; /* Number of times an L2P entry was updated in the page since it was last persisted */
42 	TAILQ_HEAD(, ftl_l2p_page_wait_ctx) ppe_list; /* for deferred pins */
43 	TAILQ_ENTRY(ftl_l2p_page) list_entry;
44 	uint64_t page_no;
45 	enum ftl_l2p_page_state state;
46 	uint64_t pin_ref_cnt;
47 	struct ftl_l2p_cache_page_io_ctx ctx;
48 	bool on_lru_list;
49 	void *page_buffer;
50 	uint64_t ckpt_seq_id;
51 	ftl_df_obj_id obj_id;
52 };
53 
54 struct ftl_l2p_page_set;
55 
56 struct ftl_l2p_page_wait_ctx {
57 	uint16_t	pg_pin_issued;
58 	uint16_t	pg_pin_completed;
59 	struct ftl_l2p_page_set *parent;
60 	uint64_t	pg_no;
61 	TAILQ_ENTRY(ftl_l2p_page_wait_ctx) list_entry;
62 };
63 
64 /* A L2P page contains 1024 4B entries (or 512 8B ones for big drives).
65  * Currently internal IO will only pin 1 LBA at a time, so only one entry should be needed.
66  * User IO is split on internal xfer_size boundaries, which is currently set to 1MiB (256 blocks),
67  * so one entry should also be enough.
68  * TODO: We should probably revisit this though, when/if the xfer_size is based on io requirements of the
69  * bottom device (e.g. RAID5F), since then big IOs (especially unaligned ones) could potentially break this.
70  */
71 #define L2P_MAX_PAGES_TO_PIN 4
72 struct ftl_l2p_page_set {
73 	uint16_t to_pin_cnt;
74 	uint16_t pinned_cnt;
75 	uint16_t pin_fault_cnt;
76 	uint8_t locked;
77 	uint8_t deferred;
78 	struct ftl_l2p_pin_ctx *pin_ctx;
79 	TAILQ_ENTRY(ftl_l2p_page_set) list_entry;
80 	struct ftl_l2p_page_wait_ctx entry[L2P_MAX_PAGES_TO_PIN];
81 };
82 
83 struct ftl_l2p_l1_map_entry {
84 	ftl_df_obj_id page_obj_id;
85 };
86 
87 enum ftl_l2p_cache_state {
88 	L2P_CACHE_INIT,
89 	L2P_CACHE_RUNNING,
90 	L2P_CACHE_IN_SHUTDOWN,
91 	L2P_CACHE_SHUTDOWN_DONE,
92 };
93 
94 struct ftl_l2p_cache_process_ctx {
95 	int status;
96 	ftl_l2p_cb cb;
97 	void *cb_ctx;
98 	uint64_t idx;
99 	uint64_t qd;
100 };
101 
102 struct ftl_l2p_cache {
103 	struct spdk_ftl_dev *dev;
104 	struct ftl_l2p_l1_map_entry *l2_mapping;
105 	struct ftl_md *l2_md;
106 	struct ftl_md *l2_ctx_md;
107 	struct ftl_mempool *l2_ctx_pool;
108 	struct ftl_md *l1_md;
109 
110 	TAILQ_HEAD(l2p_lru_list, ftl_l2p_page) lru_list;
111 	/* TODO: A lot of / and % operations are done on this value, consider adding a shift based field and calculactions instead */
112 	uint64_t lbas_in_page;
113 	uint64_t num_pages;		/* num pages to hold the entire L2P */
114 
115 	uint64_t ios_in_flight;		/* Currently in flight IOs, to determine l2p shutdown readiness */
116 	enum ftl_l2p_cache_state state;
117 	uint32_t l2_pgs_avail;
118 	uint32_t l2_pgs_evicting;
119 	uint32_t l2_pgs_resident_max;
120 	uint32_t evict_keep;
121 	struct ftl_mempool *page_sets_pool;
122 	TAILQ_HEAD(, ftl_l2p_page_set) deferred_page_set_list; /* for deferred page sets */
123 
124 	/* Process unmap in background */
125 	struct {
126 #define FTL_L2P_MAX_LAZY_UNMAP_QD 1
127 		/* Unmap queue depth */
128 		uint32_t qd;
129 		/* Currently processed page */
130 		uint64_t page_no;
131 		/* Context for page pinning */
132 		struct ftl_l2p_pin_ctx pin_ctx;
133 	} lazy_unmap;
134 
135 	/* This is a context for a management process */
136 	struct ftl_l2p_cache_process_ctx mctx;
137 
138 	/* MD layout cache: Offset on a device in FTL_BLOCK_SIZE unit */
139 	uint64_t cache_layout_offset;
140 
141 	/* MD layout cache: Device of region */
142 	struct spdk_bdev_desc *cache_layout_bdev_desc;
143 
144 	/* MD layout cache: IO channel of region */
145 	struct spdk_io_channel *cache_layout_ioch;
146 };
147 
148 typedef void (*ftl_l2p_cache_clear_cb)(struct ftl_l2p_cache *cache, int status, void *ctx_page);
149 typedef void (*ftl_l2p_cache_persist_cb)(struct ftl_l2p_cache *cache, int status, void *ctx_page);
150 typedef void (*ftl_l2p_cache_sync_cb)(struct spdk_ftl_dev *dev, int status, void *page,
151 				      void *user_ctx);
152 
153 static bool page_set_is_done(struct ftl_l2p_page_set *page_set);
154 static void page_set_end(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache,
155 			 struct ftl_l2p_page_set *page_set);
156 static void page_out_io_retry(void *arg);
157 static void page_in_io_retry(void *arg);
158 
159 static inline void
160 ftl_l2p_page_queue_wait_ctx(struct ftl_l2p_page *page,
161 			    struct ftl_l2p_page_wait_ctx *ppe)
162 {
163 	TAILQ_INSERT_TAIL(&page->ppe_list, ppe, list_entry);
164 }
165 
166 static inline uint64_t
167 ftl_l2p_cache_get_l1_page_size(void)
168 {
169 	return 1UL << 12;
170 }
171 
172 static inline uint64_t
173 ftl_l2p_cache_get_lbas_in_page(struct ftl_l2p_cache *cache)
174 {
175 	return cache->lbas_in_page;
176 }
177 
178 static inline size_t
179 ftl_l2p_cache_get_page_all_size(void)
180 {
181 	return sizeof(struct ftl_l2p_page) + ftl_l2p_cache_get_l1_page_size();
182 }
183 
184 static void
185 ftl_l2p_cache_lru_remove_page(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
186 {
187 	assert(page);
188 	assert(page->on_lru_list);
189 
190 	TAILQ_REMOVE(&cache->lru_list, page, list_entry);
191 	page->on_lru_list = false;
192 }
193 
194 static void
195 ftl_l2p_cache_lru_add_page(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
196 {
197 	assert(page);
198 	assert(!page->on_lru_list);
199 
200 	TAILQ_INSERT_HEAD(&cache->lru_list, page, list_entry);
201 
202 	page->on_lru_list = true;
203 }
204 
205 static void
206 ftl_l2p_cache_lru_promote_page(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
207 {
208 	if (!page->on_lru_list) {
209 		return;
210 	}
211 
212 	ftl_l2p_cache_lru_remove_page(cache, page);
213 	ftl_l2p_cache_lru_add_page(cache, page);
214 }
215 
216 static inline void
217 ftl_l2p_cache_page_insert(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
218 {
219 	struct ftl_l2p_l1_map_entry *me = cache->l2_mapping;
220 	assert(me);
221 
222 	assert(me[page->page_no].page_obj_id == FTL_DF_OBJ_ID_INVALID);
223 	me[page->page_no].page_obj_id = page->obj_id;
224 }
225 
226 static void
227 ftl_l2p_cache_page_remove(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
228 {
229 	struct ftl_l2p_l1_map_entry *me = cache->l2_mapping;
230 	assert(me);
231 	assert(me[page->page_no].page_obj_id != FTL_DF_OBJ_ID_INVALID);
232 	assert(TAILQ_EMPTY(&page->ppe_list));
233 
234 	me[page->page_no].page_obj_id = FTL_DF_OBJ_ID_INVALID;
235 	cache->l2_pgs_avail++;
236 	ftl_mempool_put(cache->l2_ctx_pool, page);
237 }
238 
239 static inline struct ftl_l2p_page *
240 ftl_l2p_cache_get_coldest_page(struct ftl_l2p_cache *cache)
241 {
242 	return TAILQ_LAST(&cache->lru_list, l2p_lru_list);
243 }
244 
245 static inline struct ftl_l2p_page *
246 ftl_l2p_cache_get_hotter_page(struct ftl_l2p_page *page)
247 {
248 	return TAILQ_PREV(page, l2p_lru_list, list_entry);
249 }
250 
251 static inline uint64_t
252 ftl_l2p_cache_page_get_bdev_offset(struct ftl_l2p_cache *cache,
253 				   struct ftl_l2p_page *page)
254 {
255 	return cache->cache_layout_offset + page->page_no;
256 }
257 
258 static inline struct spdk_bdev_desc *
259 ftl_l2p_cache_get_bdev_desc(struct ftl_l2p_cache *cache)
260 {
261 	return cache->cache_layout_bdev_desc;
262 }
263 
264 static inline struct spdk_io_channel *
265 ftl_l2p_cache_get_bdev_iochannel(struct ftl_l2p_cache *cache)
266 {
267 	return cache->cache_layout_ioch;
268 }
269 
270 static struct ftl_l2p_page *
271 ftl_l2p_cache_page_alloc(struct ftl_l2p_cache *cache, size_t page_no)
272 {
273 	struct ftl_l2p_page *page = ftl_mempool_get(cache->l2_ctx_pool);
274 	ftl_bug(!page);
275 
276 	cache->l2_pgs_avail--;
277 
278 	memset(page, 0, sizeof(*page));
279 
280 	page->obj_id = ftl_mempool_get_df_obj_id(cache->l2_ctx_pool, page);
281 
282 	page->page_buffer = (char *)ftl_md_get_buffer(cache->l1_md) + ftl_mempool_get_df_obj_index(
283 				    cache->l2_ctx_pool, page) * FTL_BLOCK_SIZE;
284 
285 	TAILQ_INIT(&page->ppe_list);
286 
287 	page->page_no = page_no;
288 	page->state = L2P_CACHE_PAGE_INIT;
289 
290 	return page;
291 }
292 
293 static inline bool
294 ftl_l2p_cache_page_can_remove(struct ftl_l2p_page *page)
295 {
296 	return (!page->updates &&
297 		page->state != L2P_CACHE_PAGE_INIT &&
298 		!page->pin_ref_cnt);
299 }
300 
301 static inline ftl_addr
302 ftl_l2p_cache_get_addr(struct spdk_ftl_dev *dev,
303 		       struct ftl_l2p_cache *cache, struct ftl_l2p_page *page, uint64_t lba)
304 {
305 	return ftl_addr_load(dev, page->page_buffer, lba % cache->lbas_in_page);
306 }
307 
308 static inline void
309 ftl_l2p_cache_set_addr(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache,
310 		       struct ftl_l2p_page *page, uint64_t lba, ftl_addr addr)
311 {
312 	ftl_addr_store(dev, page->page_buffer, lba % cache->lbas_in_page, addr);
313 }
314 
315 static void
316 ftl_l2p_page_set_invalid(struct spdk_ftl_dev *dev, struct ftl_l2p_page *page)
317 {
318 	ftl_addr addr;
319 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
320 	uint64_t naddr;
321 
322 	page->updates++;
323 
324 	naddr = ftl_l2p_cache_get_lbas_in_page(cache);
325 	for (uint64_t i = 0; i < naddr; i++) {
326 		addr = ftl_addr_load(dev, page->page_buffer, i);
327 		if (addr == FTL_ADDR_INVALID) {
328 			continue;
329 		}
330 
331 		ftl_invalidate_addr(dev, addr);
332 		ftl_l2p_cache_set_addr(dev, cache, page, i, FTL_ADDR_INVALID);
333 	}
334 }
335 
336 static inline void
337 ftl_l2p_cache_page_pin(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
338 {
339 	page->pin_ref_cnt++;
340 	/* Pinned pages can't be evicted (since L2P sets/gets will be executed on it), so remove them from LRU */
341 	if (page->on_lru_list) {
342 		ftl_l2p_cache_lru_remove_page(cache, page);
343 	}
344 }
345 
346 static inline void
347 ftl_l2p_cache_page_unpin(struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
348 {
349 	page->pin_ref_cnt--;
350 	if (!page->pin_ref_cnt && !page->on_lru_list && page->state != L2P_CACHE_PAGE_FLUSHING) {
351 		/* L2P_CACHE_PAGE_FLUSHING: the page is currently being evicted.
352 		 * In such a case, the page can't be returned to the rank list, because
353 		 * the ongoing eviction will remove it if no pg updates had happened.
354 		 * Moreover, the page could make it to the top of the rank list and be
355 		 * selected for another eviction, while the ongoing one did not finish yet.
356 		 *
357 		 * Depending on the page updates tracker, the page will be evicted
358 		 * or returned to the rank list in context of the eviction completion
359 		 * cb - see page_out_io_complete().
360 		 */
361 		ftl_l2p_cache_lru_add_page(cache, page);
362 	}
363 }
364 
365 static inline bool
366 ftl_l2p_cache_page_can_evict(struct ftl_l2p_page *page)
367 {
368 	return (page->state == L2P_CACHE_PAGE_FLUSHING ||
369 		page->state == L2P_CACHE_PAGE_PERSISTING ||
370 		page->state == L2P_CACHE_PAGE_INIT ||
371 		page->pin_ref_cnt) ? false : true;
372 }
373 
374 static bool
375 ftl_l2p_cache_evict_continue(struct ftl_l2p_cache *cache)
376 {
377 	return cache->l2_pgs_avail + cache->l2_pgs_evicting < cache->evict_keep;
378 }
379 
380 static void *
381 _ftl_l2p_cache_init(struct spdk_ftl_dev *dev, size_t addr_size, uint64_t l2p_size)
382 {
383 	struct ftl_l2p_cache *cache;
384 	uint64_t l2_pages = spdk_divide_round_up(l2p_size, ftl_l2p_cache_get_l1_page_size());
385 	size_t l2_size = l2_pages * sizeof(struct ftl_l2p_l1_map_entry);
386 
387 	cache = calloc(1, sizeof(struct ftl_l2p_cache));
388 	if (cache == NULL) {
389 		return NULL;
390 	}
391 	cache->dev = dev;
392 
393 	cache->l2_md = ftl_md_create(dev,
394 				     spdk_divide_round_up(l2_size, FTL_BLOCK_SIZE), 0,
395 				     FTL_L2P_CACHE_MD_NAME_L2,
396 				     ftl_md_create_shm_flags(dev), NULL);
397 
398 	if (cache->l2_md == NULL) {
399 		goto fail_l2_md;
400 	}
401 	cache->l2_mapping = ftl_md_get_buffer(cache->l2_md);
402 
403 	cache->lbas_in_page = dev->layout.l2p.lbas_in_page;
404 	cache->num_pages = l2_pages;
405 
406 	return cache;
407 fail_l2_md:
408 	free(cache);
409 	return NULL;
410 }
411 
412 static struct ftl_l2p_page *
413 get_l2p_page_by_df_id(struct ftl_l2p_cache *cache, size_t page_no)
414 {
415 	struct ftl_l2p_l1_map_entry *me = cache->l2_mapping;
416 	ftl_df_obj_id obj_id = me[page_no].page_obj_id;
417 
418 	if (obj_id != FTL_DF_OBJ_ID_INVALID) {
419 		return ftl_mempool_get_df_ptr(cache->l2_ctx_pool, obj_id);
420 	}
421 
422 	return NULL;
423 }
424 
425 int
426 ftl_l2p_cache_init(struct spdk_ftl_dev *dev)
427 {
428 	uint64_t l2p_size = dev->num_lbas * dev->layout.l2p.addr_size;
429 	struct ftl_l2p_cache *cache;
430 	const struct ftl_layout_region *reg;
431 	void *l2p = _ftl_l2p_cache_init(dev, dev->layout.l2p.addr_size, l2p_size);
432 	size_t page_sets_pool_size = 1 << 15;
433 	size_t max_resident_size, max_resident_pgs;
434 
435 	if (!l2p) {
436 		return -1;
437 	}
438 	dev->l2p = l2p;
439 
440 	cache = (struct ftl_l2p_cache *)dev->l2p;
441 	cache->page_sets_pool = ftl_mempool_create(page_sets_pool_size,
442 				sizeof(struct ftl_l2p_page_set),
443 				64, SPDK_ENV_SOCKET_ID_ANY);
444 	if (!cache->page_sets_pool) {
445 		return -1;
446 	}
447 
448 	max_resident_size = dev->conf.l2p_dram_limit << 20;
449 	max_resident_pgs = max_resident_size / ftl_l2p_cache_get_page_all_size();
450 
451 	if (max_resident_pgs > cache->num_pages) {
452 		SPDK_NOTICELOG("l2p memory limit higher than entire L2P size\n");
453 		max_resident_pgs = cache->num_pages;
454 	}
455 
456 	/* Round down max res pgs to the nearest # of l2/l1 pgs */
457 	max_resident_size = max_resident_pgs * ftl_l2p_cache_get_page_all_size();
458 	SPDK_NOTICELOG("l2p maximum resident size is: %"PRIu64" (of %"PRIu64") MiB\n",
459 		       max_resident_size >> 20, dev->conf.l2p_dram_limit);
460 
461 	TAILQ_INIT(&cache->deferred_page_set_list);
462 	TAILQ_INIT(&cache->lru_list);
463 
464 	cache->l2_ctx_md = ftl_md_create(dev,
465 					 spdk_divide_round_up(max_resident_pgs * SPDK_ALIGN_CEIL(sizeof(struct ftl_l2p_page), 64),
466 							 FTL_BLOCK_SIZE), 0, FTL_L2P_CACHE_MD_NAME_L2_CTX, ftl_md_create_shm_flags(dev), NULL);
467 
468 	if (cache->l2_ctx_md == NULL) {
469 		return -1;
470 	}
471 
472 	cache->l2_pgs_resident_max = max_resident_pgs;
473 	cache->l2_pgs_avail = max_resident_pgs;
474 	cache->l2_pgs_evicting = 0;
475 	cache->l2_ctx_pool = ftl_mempool_create_ext(ftl_md_get_buffer(cache->l2_ctx_md),
476 			     max_resident_pgs, sizeof(struct ftl_l2p_page), 64);
477 
478 	if (cache->l2_ctx_pool == NULL) {
479 		return -1;
480 	}
481 
482 #define FTL_L2P_CACHE_PAGE_AVAIL_MAX            16UL << 10
483 #define FTL_L2P_CACHE_PAGE_AVAIL_RATIO          5UL
484 	cache->evict_keep = spdk_divide_round_up(cache->num_pages * FTL_L2P_CACHE_PAGE_AVAIL_RATIO, 100);
485 	cache->evict_keep = spdk_min(FTL_L2P_CACHE_PAGE_AVAIL_MAX, cache->evict_keep);
486 
487 	if (!ftl_fast_startup(dev) && !ftl_fast_recovery(dev)) {
488 		memset(cache->l2_mapping, (int)FTL_DF_OBJ_ID_INVALID, ftl_md_get_buffer_size(cache->l2_md));
489 		ftl_mempool_initialize_ext(cache->l2_ctx_pool);
490 	}
491 
492 	cache->l1_md = ftl_md_create(dev,
493 				     max_resident_pgs, 0,
494 				     FTL_L2P_CACHE_MD_NAME_L1,
495 				     ftl_md_create_shm_flags(dev), NULL);
496 
497 	if (cache->l1_md == NULL) {
498 		return -1;
499 	}
500 
501 	/* Cache MD layout */
502 	reg = &dev->layout.region[FTL_LAYOUT_REGION_TYPE_L2P];
503 	cache->cache_layout_offset = reg->current.offset;
504 	cache->cache_layout_bdev_desc = reg->bdev_desc;
505 	cache->cache_layout_ioch = reg->ioch;
506 
507 	return 0;
508 }
509 
510 static void
511 ftl_l2p_cache_deinit_l2(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache)
512 {
513 	ftl_md_destroy(cache->l2_ctx_md, ftl_md_destroy_shm_flags(dev));
514 	cache->l2_ctx_md = NULL;
515 
516 	ftl_mempool_destroy_ext(cache->l2_ctx_pool);
517 	cache->l2_ctx_pool = NULL;
518 
519 	ftl_md_destroy(cache->l1_md, ftl_md_destroy_shm_flags(dev));
520 	cache->l1_md = NULL;
521 
522 	ftl_mempool_destroy(cache->page_sets_pool);
523 	cache->page_sets_pool = NULL;
524 }
525 
526 static void
527 _ftl_l2p_cache_deinit(struct spdk_ftl_dev *dev)
528 {
529 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
530 
531 	ftl_l2p_cache_deinit_l2(dev, cache);
532 	ftl_md_destroy(cache->l2_md, ftl_md_destroy_shm_flags(dev));
533 	free(cache);
534 }
535 
536 void
537 ftl_l2p_cache_deinit(struct spdk_ftl_dev *dev)
538 {
539 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
540 
541 	if (!cache) {
542 		return;
543 	}
544 	assert(cache->state == L2P_CACHE_SHUTDOWN_DONE || cache->state == L2P_CACHE_INIT);
545 
546 	_ftl_l2p_cache_deinit(dev);
547 	dev->l2p = 0;
548 }
549 
550 static void
551 process_init_ctx(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache,
552 		 ftl_l2p_cb cb, void *cb_ctx)
553 {
554 	struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx;
555 
556 	assert(NULL == ctx->cb_ctx);
557 	assert(0 == cache->l2_pgs_evicting);
558 
559 	memset(ctx, 0, sizeof(*ctx));
560 
561 	ctx->cb = cb;
562 	ctx->cb_ctx = cb_ctx;
563 }
564 
565 static void
566 process_finish(struct ftl_l2p_cache *cache)
567 {
568 	struct ftl_l2p_cache_process_ctx ctx = cache->mctx;
569 
570 	assert(cache->l2_pgs_avail == cache->l2_pgs_resident_max);
571 	assert(0 == ctx.qd);
572 
573 	memset(&cache->mctx, 0, sizeof(cache->mctx));
574 	ctx.cb(cache->dev, ctx.status, ctx.cb_ctx);
575 }
576 
577 static void process_page_out_retry(void *_page);
578 static void process_persist(struct ftl_l2p_cache *cache);
579 
580 static void
581 process_page_in(struct ftl_l2p_page *page, spdk_bdev_io_completion_cb cb)
582 {
583 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)page->ctx.cache;
584 	int rc;
585 
586 	assert(page->page_buffer);
587 
588 	rc = ftl_nv_cache_bdev_read_blocks_with_md(cache->dev, ftl_l2p_cache_get_bdev_desc(cache),
589 			ftl_l2p_cache_get_bdev_iochannel(cache),
590 			page->page_buffer, NULL, ftl_l2p_cache_page_get_bdev_offset(cache, page),
591 			1, cb, page);
592 
593 	if (rc) {
594 		cb(NULL, false, page);
595 	}
596 }
597 
598 static void
599 process_persist_page_out_cb(struct spdk_bdev_io *bdev_io, bool success, void *arg)
600 {
601 	struct ftl_l2p_page *page = arg;
602 	struct ftl_l2p_cache *cache = page->ctx.cache;
603 	struct spdk_ftl_dev *dev = cache->dev;
604 	struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx;
605 
606 	assert(bdev_io);
607 	ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io);
608 	spdk_bdev_free_io(bdev_io);
609 
610 	if (!success) {
611 		ctx->status = -EIO;
612 	}
613 
614 	if (ftl_bitmap_get(dev->unmap_map, ctx->idx)) {
615 		/*
616 		 * Page had been unmapped, in persist path before IO, it was invalidated entirely
617 		 * now clear unmap flag
618 		 */
619 		ftl_bitmap_clear(dev->unmap_map, page->page_no);
620 	}
621 	ftl_l2p_cache_page_remove(cache, page);
622 
623 	ctx->qd--;
624 	process_persist(cache);
625 }
626 
627 static void
628 process_page_out(struct ftl_l2p_page *page, spdk_bdev_io_completion_cb cb)
629 {
630 	struct spdk_bdev *bdev;
631 	struct spdk_bdev_io_wait_entry *bdev_io_wait;
632 	struct ftl_l2p_cache *cache = page->ctx.cache;
633 	struct spdk_ftl_dev *dev = cache->dev;
634 	int rc;
635 
636 	assert(page->page_buffer);
637 
638 	rc = ftl_nv_cache_bdev_write_blocks_with_md(dev, ftl_l2p_cache_get_bdev_desc(cache),
639 			ftl_l2p_cache_get_bdev_iochannel(cache),
640 			page->page_buffer, NULL, ftl_l2p_cache_page_get_bdev_offset(cache, page),
641 			1, cb, page);
642 
643 	if (spdk_likely(0 == rc)) {
644 		return;
645 	}
646 
647 	if (rc == -ENOMEM) {
648 		bdev = spdk_bdev_desc_get_bdev(ftl_l2p_cache_get_bdev_desc(cache));
649 		bdev_io_wait = &page->ctx.bdev_io_wait;
650 		bdev_io_wait->bdev = bdev;
651 		bdev_io_wait->cb_fn = process_page_out_retry;
652 		bdev_io_wait->cb_arg = page;
653 		page->ctx.cb = cb;
654 
655 		rc = spdk_bdev_queue_io_wait(bdev, ftl_l2p_cache_get_bdev_iochannel(cache), bdev_io_wait);
656 		ftl_bug(rc);
657 	} else {
658 		ftl_abort();
659 	}
660 }
661 
662 static void
663 process_page_out_retry(void *_page)
664 {
665 	struct ftl_l2p_page *page = _page;
666 
667 	process_page_out(page, page->ctx.cb);
668 }
669 
670 static void process_unmap(struct ftl_l2p_cache *cache);
671 
672 static void
673 process_unmap_page_out_cb(struct spdk_bdev_io *bdev_io, bool success, void *ctx_page)
674 {
675 	struct ftl_l2p_page *page = (struct ftl_l2p_page *)ctx_page;
676 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)page->ctx.cache;
677 	struct spdk_ftl_dev *dev = cache->dev;
678 	struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx;
679 
680 	assert(bdev_io);
681 	ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io);
682 	spdk_bdev_free_io(bdev_io);
683 
684 	if (!success) {
685 		ctx->status = -EIO;
686 	}
687 
688 	assert(!page->on_lru_list);
689 	assert(ftl_bitmap_get(dev->unmap_map, page->page_no));
690 	ftl_bitmap_clear(dev->unmap_map, page->page_no);
691 	ftl_l2p_cache_page_remove(cache, page);
692 
693 	ctx->qd--;
694 	process_unmap(cache);
695 }
696 
697 static void
698 process_unmap_page_in_cb(struct spdk_bdev_io *bdev_io, bool success, void *ctx_page)
699 {
700 	struct ftl_l2p_page *page = (struct ftl_l2p_page *)ctx_page;
701 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)page->ctx.cache;
702 	struct spdk_ftl_dev *dev = cache->dev;
703 	struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx;
704 
705 	if (bdev_io) {
706 		ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io);
707 		spdk_bdev_free_io(bdev_io);
708 	}
709 	if (success) {
710 		assert(ftl_bitmap_get(dev->unmap_map, page->page_no));
711 		ftl_l2p_page_set_invalid(dev, page);
712 		process_page_out(page, process_unmap_page_out_cb);
713 	} else {
714 		ctx->status = -EIO;
715 		ctx->qd--;
716 		process_unmap(cache);
717 	}
718 }
719 
720 static void
721 process_unmap(struct ftl_l2p_cache *cache)
722 {
723 	struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx;
724 
725 	while (ctx->idx < cache->num_pages && ctx->qd < 64) {
726 		struct ftl_l2p_page *page;
727 
728 		if (!ftl_bitmap_get(cache->dev->unmap_map, ctx->idx)) {
729 			/* Page had not been unmapped, continue */
730 			ctx->idx++;
731 			continue;
732 		}
733 
734 		/* All pages were removed in persist phase */
735 		assert(get_l2p_page_by_df_id(cache, ctx->idx) == NULL);
736 
737 		/* Allocate page to invalidate it */
738 		page = ftl_l2p_cache_page_alloc(cache, ctx->idx);
739 		if (!page) {
740 			/* All pages utilized so far, continue when they will be back available */
741 			assert(ctx->qd);
742 			break;
743 		}
744 
745 		page->state = L2P_CACHE_PAGE_CLEARING;
746 		page->ctx.cache = cache;
747 
748 		ftl_l2p_cache_page_insert(cache, page);
749 		process_page_in(page, process_unmap_page_in_cb);
750 
751 		ctx->qd++;
752 		ctx->idx++;
753 	}
754 
755 	if (0 == ctx->qd) {
756 		process_finish(cache);
757 	}
758 }
759 
760 void
761 ftl_l2p_cache_unmap(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
762 {
763 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
764 
765 	process_init_ctx(dev, cache, cb, cb_ctx);
766 	process_unmap(cache);
767 }
768 
769 static void
770 clear_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
771 {
772 	ftl_l2p_cb cb = md->owner.private;
773 	void *cb_cntx = md->owner.cb_ctx;
774 
775 	cb(dev, status, cb_cntx);
776 }
777 
778 void
779 ftl_l2p_cache_clear(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
780 {
781 	struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_L2P];
782 	ftl_addr invalid_addr = FTL_ADDR_INVALID;
783 
784 	md->cb =  clear_cb;
785 	md->owner.cb_ctx = cb_ctx;
786 	md->owner.private = cb;
787 
788 	ftl_md_clear(md, invalid_addr, NULL);
789 }
790 
791 static void
792 l2p_shm_restore_clean(struct spdk_ftl_dev *dev)
793 {
794 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
795 	struct ftl_l2p_l1_map_entry *me = cache->l2_mapping;
796 	struct ftl_l2p_page *page;
797 	ftl_df_obj_id obj_id;
798 	uint64_t page_no;
799 
800 	for (page_no = 0; page_no < cache->num_pages; ++page_no) {
801 		obj_id = me[page_no].page_obj_id;
802 		if (obj_id == FTL_DF_OBJ_ID_INVALID) {
803 			continue;
804 		}
805 
806 		page = ftl_mempool_claim_df(cache->l2_ctx_pool, obj_id);
807 		assert(page);
808 		assert(page->obj_id == ftl_mempool_get_df_obj_id(cache->l2_ctx_pool, page));
809 		assert(page->page_no == page_no);
810 		assert(page->state != L2P_CACHE_PAGE_INIT);
811 		assert(page->state != L2P_CACHE_PAGE_CLEARING);
812 		assert(cache->l2_pgs_avail > 0);
813 		cache->l2_pgs_avail--;
814 
815 		page->page_buffer = (char *)ftl_md_get_buffer(cache->l1_md) + ftl_mempool_get_df_obj_index(
816 					    cache->l2_ctx_pool, page) * FTL_BLOCK_SIZE;
817 
818 		TAILQ_INIT(&page->ppe_list);
819 
820 		page->pin_ref_cnt = 0;
821 		page->on_lru_list = 0;
822 		memset(&page->ctx, 0, sizeof(page->ctx));
823 
824 		ftl_l2p_cache_lru_add_page(cache, page);
825 	}
826 
827 	ftl_mempool_initialize_ext(cache->l2_ctx_pool);
828 }
829 
830 static void
831 l2p_shm_restore_dirty(struct spdk_ftl_dev *dev)
832 {
833 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
834 	struct ftl_l2p_l1_map_entry *me = cache->l2_mapping;
835 	struct ftl_l2p_page *page;
836 	ftl_df_obj_id obj_id;
837 	uint64_t page_no;
838 
839 	for (page_no = 0; page_no < cache->num_pages; ++page_no) {
840 		obj_id = me[page_no].page_obj_id;
841 		if (obj_id == FTL_DF_OBJ_ID_INVALID) {
842 			continue;
843 		}
844 
845 		page = ftl_mempool_claim_df(cache->l2_ctx_pool, obj_id);
846 		assert(page);
847 		assert(page->obj_id == ftl_mempool_get_df_obj_id(cache->l2_ctx_pool, page));
848 		assert(page->page_no == page_no);
849 		assert(page->state != L2P_CACHE_PAGE_CLEARING);
850 		assert(cache->l2_pgs_avail > 0);
851 		cache->l2_pgs_avail--;
852 
853 		if (page->state == L2P_CACHE_PAGE_INIT) {
854 			me[page_no].page_obj_id = FTL_DF_OBJ_ID_INVALID;
855 			cache->l2_pgs_avail++;
856 			ftl_mempool_release_df(cache->l2_ctx_pool, obj_id);
857 			continue;
858 		}
859 
860 		page->state = L2P_CACHE_PAGE_READY;
861 		/* Assume page is dirty after crash */
862 		page->updates = 1;
863 		page->page_buffer = (char *)ftl_md_get_buffer(cache->l1_md) + ftl_mempool_get_df_obj_index(
864 					    cache->l2_ctx_pool, page) * FTL_BLOCK_SIZE;
865 
866 		TAILQ_INIT(&page->ppe_list);
867 
868 		page->pin_ref_cnt = 0;
869 		page->on_lru_list = 0;
870 		memset(&page->ctx, 0, sizeof(page->ctx));
871 
872 		ftl_l2p_cache_lru_add_page(cache, page);
873 	}
874 
875 	ftl_mempool_initialize_ext(cache->l2_ctx_pool);
876 }
877 
878 void
879 ftl_l2p_cache_restore(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
880 {
881 	if (ftl_fast_startup(dev)) {
882 		l2p_shm_restore_clean(dev);
883 	}
884 
885 	if (ftl_fast_recovery(dev)) {
886 		l2p_shm_restore_dirty(dev);
887 	}
888 
889 	cb(dev, 0, cb_ctx);
890 }
891 
892 static void
893 process_persist(struct ftl_l2p_cache *cache)
894 {
895 	struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx;
896 	struct spdk_ftl_dev *dev = cache->dev;
897 
898 	while (ctx->idx < cache->num_pages && ctx->qd < 64) {
899 		struct ftl_l2p_page *page = get_l2p_page_by_df_id(cache, ctx->idx);
900 		ctx->idx++;
901 
902 		if (!page) {
903 			continue;
904 		}
905 
906 		/* Finished unmap if the page was marked */
907 		if (ftl_bitmap_get(dev->unmap_map, ctx->idx)) {
908 			ftl_l2p_page_set_invalid(dev, page);
909 		}
910 
911 		if (page->on_lru_list) {
912 			ftl_l2p_cache_lru_remove_page(cache, page);
913 		}
914 
915 		if (page->updates) {
916 			/* Need to persist the page */
917 			page->state = L2P_CACHE_PAGE_PERSISTING;
918 			page->ctx.cache = cache;
919 			ctx->qd++;
920 			process_page_out(page, process_persist_page_out_cb);
921 		} else {
922 			ftl_l2p_cache_page_remove(cache, page);
923 		}
924 	}
925 
926 	if (0 == ctx->qd) {
927 		process_finish(cache);
928 	}
929 }
930 
931 void
932 ftl_l2p_cache_persist(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
933 {
934 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
935 
936 	process_init_ctx(dev, cache, cb, cb_ctx);
937 	process_persist(cache);
938 }
939 
940 bool
941 ftl_l2p_cache_is_halted(struct spdk_ftl_dev *dev)
942 {
943 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
944 
945 	return cache->state == L2P_CACHE_SHUTDOWN_DONE;
946 }
947 
948 void
949 ftl_l2p_cache_halt(struct spdk_ftl_dev *dev)
950 {
951 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
952 
953 	if (cache->state != L2P_CACHE_SHUTDOWN_DONE) {
954 		cache->state = L2P_CACHE_IN_SHUTDOWN;
955 		if (!cache->ios_in_flight && !cache->l2_pgs_evicting) {
956 			cache->state = L2P_CACHE_SHUTDOWN_DONE;
957 		}
958 	}
959 }
960 
961 void
962 ftl_l2p_cache_resume(struct spdk_ftl_dev *dev)
963 {
964 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
965 
966 	assert(cache->state == L2P_CACHE_INIT);
967 	cache->state = L2P_CACHE_RUNNING;
968 }
969 
970 static inline struct ftl_l2p_page *
971 get_page(struct ftl_l2p_cache *cache, uint64_t lba)
972 {
973 	return get_l2p_page_by_df_id(cache, lba / cache->lbas_in_page);
974 }
975 
976 static inline void
977 ftl_l2p_cache_init_page_set(struct ftl_l2p_page_set *page_set, struct ftl_l2p_pin_ctx *pin_ctx)
978 {
979 	page_set->to_pin_cnt = 0;
980 	page_set->pinned_cnt = 0;
981 	page_set->pin_fault_cnt = 0;
982 	page_set->locked = 0;
983 	page_set->deferred = 0;
984 	page_set->pin_ctx = pin_ctx;
985 }
986 
987 static inline bool
988 ftl_l2p_cache_running(struct ftl_l2p_cache *cache)
989 {
990 	return cache->state == L2P_CACHE_RUNNING;
991 }
992 
993 static inline bool
994 ftl_l2p_cache_page_is_pinnable(struct ftl_l2p_page *page)
995 {
996 	return page->state != L2P_CACHE_PAGE_INIT;
997 }
998 
999 void
1000 ftl_l2p_cache_pin(struct spdk_ftl_dev *dev, struct ftl_l2p_pin_ctx *pin_ctx)
1001 {
1002 	assert(dev->num_lbas >= pin_ctx->lba + pin_ctx->count);
1003 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
1004 	struct ftl_l2p_page_set *page_set;
1005 	bool defer_pin = false;
1006 
1007 	/* Calculate first and last page to pin, count of them */
1008 	uint64_t start = pin_ctx->lba / cache->lbas_in_page;
1009 	uint64_t end = (pin_ctx->lba + pin_ctx->count - 1) / cache->lbas_in_page;
1010 	uint64_t count = end - start + 1;
1011 	uint64_t i;
1012 
1013 	if (spdk_unlikely(count > L2P_MAX_PAGES_TO_PIN)) {
1014 		ftl_l2p_pin_complete(dev, -E2BIG, pin_ctx);
1015 		return;
1016 	}
1017 
1018 	/* Get and initialize page sets */
1019 	assert(ftl_l2p_cache_running(cache));
1020 	page_set = ftl_mempool_get(cache->page_sets_pool);
1021 	if (!page_set) {
1022 		ftl_l2p_pin_complete(dev, -EAGAIN, pin_ctx);
1023 		return;
1024 	}
1025 	ftl_l2p_cache_init_page_set(page_set, pin_ctx);
1026 
1027 	struct ftl_l2p_page_wait_ctx *entry = page_set->entry;
1028 	for (i = start; i <= end; i++, entry++) {
1029 		struct ftl_l2p_page *page;
1030 		entry->parent = page_set;
1031 		entry->pg_no = i;
1032 		entry->pg_pin_completed = false;
1033 		entry->pg_pin_issued = false;
1034 
1035 		page_set->to_pin_cnt++;
1036 
1037 		/* Try get page and pin */
1038 		page = get_l2p_page_by_df_id(cache, i);
1039 		if (page) {
1040 			if (ftl_l2p_cache_page_is_pinnable(page)) {
1041 				/* Page available and we can pin it */
1042 				page_set->pinned_cnt++;
1043 				entry->pg_pin_issued = true;
1044 				entry->pg_pin_completed = true;
1045 				ftl_l2p_cache_page_pin(cache, page);
1046 			} else {
1047 				/* The page is being loaded */
1048 				/* Queue the page pin entry to be executed on page in */
1049 				ftl_l2p_page_queue_wait_ctx(page, entry);
1050 				entry->pg_pin_issued = true;
1051 			}
1052 		} else {
1053 			/* The page is not in the cache, queue the page_set to page in */
1054 			defer_pin = true;
1055 		}
1056 	}
1057 
1058 	/* Check if page set is done */
1059 	if (page_set_is_done(page_set)) {
1060 		page_set_end(dev, cache, page_set);
1061 	} else if (defer_pin) {
1062 		TAILQ_INSERT_TAIL(&cache->deferred_page_set_list, page_set, list_entry);
1063 		page_set->deferred = 1;
1064 	}
1065 }
1066 
1067 void
1068 ftl_l2p_cache_unpin(struct spdk_ftl_dev *dev, uint64_t lba, uint64_t count)
1069 {
1070 	assert(dev->num_lbas >= lba + count);
1071 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
1072 	struct ftl_l2p_page *page;
1073 	uint64_t start = lba / cache->lbas_in_page;
1074 	uint64_t end = (lba + count - 1) / cache->lbas_in_page;
1075 	uint64_t i;
1076 
1077 	assert(count);
1078 	assert(start < cache->num_pages);
1079 	assert(end < cache->num_pages);
1080 
1081 	for (i = start; i <= end; i++) {
1082 		page = get_l2p_page_by_df_id(cache, i);
1083 		ftl_bug(!page);
1084 		ftl_l2p_cache_page_unpin(cache, page);
1085 	}
1086 }
1087 
1088 ftl_addr
1089 ftl_l2p_cache_get(struct spdk_ftl_dev *dev, uint64_t lba)
1090 {
1091 	assert(dev->num_lbas > lba);
1092 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
1093 	struct ftl_l2p_page *page = get_page(cache, lba);
1094 	ftl_addr addr;
1095 
1096 	ftl_bug(!page);
1097 	assert(ftl_l2p_cache_running(cache));
1098 	assert(page->pin_ref_cnt);
1099 
1100 	if (ftl_bitmap_get(dev->unmap_map, page->page_no)) {
1101 		ftl_l2p_page_set_invalid(dev, page);
1102 		ftl_bitmap_clear(dev->unmap_map, page->page_no);
1103 	}
1104 
1105 	ftl_l2p_cache_lru_promote_page(cache, page);
1106 	addr = ftl_l2p_cache_get_addr(dev, cache, page, lba);
1107 
1108 	return addr;
1109 }
1110 
1111 void
1112 ftl_l2p_cache_set(struct spdk_ftl_dev *dev, uint64_t lba, ftl_addr addr)
1113 {
1114 	assert(dev->num_lbas > lba);
1115 	struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p;
1116 	struct ftl_l2p_page *page = get_page(cache, lba);
1117 
1118 	ftl_bug(!page);
1119 	assert(ftl_l2p_cache_running(cache));
1120 	assert(page->pin_ref_cnt);
1121 
1122 	if (ftl_bitmap_get(dev->unmap_map, page->page_no)) {
1123 		ftl_l2p_page_set_invalid(dev, page);
1124 		ftl_bitmap_clear(dev->unmap_map, page->page_no);
1125 	}
1126 
1127 	page->updates++;
1128 	ftl_l2p_cache_lru_promote_page(cache, page);
1129 	ftl_l2p_cache_set_addr(dev, cache, page, lba, addr);
1130 }
1131 
1132 static struct ftl_l2p_page *
1133 page_allocate(struct ftl_l2p_cache *cache, uint64_t page_no)
1134 {
1135 	struct ftl_l2p_page *page = ftl_l2p_cache_page_alloc(cache, page_no);
1136 	ftl_l2p_cache_page_insert(cache, page);
1137 
1138 	return page;
1139 }
1140 
1141 static bool
1142 page_set_is_done(struct ftl_l2p_page_set *page_set)
1143 {
1144 	if (page_set->locked) {
1145 		return false;
1146 	}
1147 
1148 	assert(page_set->pinned_cnt + page_set->pin_fault_cnt <= page_set->to_pin_cnt);
1149 	return (page_set->pinned_cnt + page_set->pin_fault_cnt == page_set->to_pin_cnt);
1150 }
1151 
1152 static void
1153 page_set_unpin(struct ftl_l2p_cache *cache, struct ftl_l2p_page_set *page_set)
1154 {
1155 	uint64_t i;
1156 	struct ftl_l2p_page_wait_ctx *pentry = page_set->entry;
1157 
1158 	for (i = 0; i < page_set->to_pin_cnt; i++, pentry++) {
1159 		struct ftl_l2p_page *pinned_page;
1160 
1161 		if (false == pentry->pg_pin_completed) {
1162 			continue;
1163 		}
1164 
1165 		pinned_page = get_l2p_page_by_df_id(cache, pentry->pg_no);
1166 		ftl_bug(!pinned_page);
1167 
1168 		ftl_l2p_cache_page_unpin(cache, pinned_page);
1169 	}
1170 }
1171 
1172 static void
1173 page_set_end(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache,
1174 	     struct ftl_l2p_page_set *page_set)
1175 {
1176 	if (spdk_likely(0 == page_set->pin_fault_cnt)) {
1177 		ftl_l2p_pin_complete(dev, 0, page_set->pin_ctx);
1178 	} else {
1179 		page_set_unpin(cache, page_set);
1180 		ftl_l2p_pin_complete(dev, -EIO, page_set->pin_ctx);
1181 	}
1182 
1183 	if (page_set->deferred) {
1184 		TAILQ_REMOVE(&cache->deferred_page_set_list, page_set, list_entry);
1185 	}
1186 
1187 	assert(0 == page_set->locked);
1188 	ftl_mempool_put(cache->page_sets_pool, page_set);
1189 }
1190 
1191 static void
1192 page_in_io_complete(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache,
1193 		    struct ftl_l2p_page *page, bool success)
1194 {
1195 	struct ftl_l2p_page_set *page_set;
1196 	struct ftl_l2p_page_wait_ctx *pentry;
1197 
1198 	cache->ios_in_flight--;
1199 
1200 	assert(0 == page->pin_ref_cnt);
1201 	assert(L2P_CACHE_PAGE_INIT == page->state);
1202 	assert(false == page->on_lru_list);
1203 
1204 	if (spdk_likely(success)) {
1205 		page->state = L2P_CACHE_PAGE_READY;
1206 	}
1207 
1208 	while ((pentry = TAILQ_FIRST(&page->ppe_list))) {
1209 		TAILQ_REMOVE(&page->ppe_list, pentry, list_entry);
1210 
1211 		page_set = pentry->parent;
1212 
1213 		assert(false == pentry->pg_pin_completed);
1214 
1215 		if (success) {
1216 			ftl_l2p_cache_page_pin(cache, page);
1217 			page_set->pinned_cnt++;
1218 			pentry->pg_pin_completed = true;
1219 		} else {
1220 			page_set->pin_fault_cnt++;
1221 		}
1222 
1223 		/* Check if page_set is done */
1224 		if (page_set_is_done(page_set)) {
1225 			page_set_end(dev, cache, page_set);
1226 		}
1227 	}
1228 
1229 	if (spdk_unlikely(!success)) {
1230 		ftl_bug(page->on_lru_list);
1231 		ftl_l2p_cache_page_remove(cache, page);
1232 	}
1233 }
1234 
1235 static void
1236 page_in_io_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
1237 {
1238 	struct ftl_l2p_page *page = cb_arg;
1239 	struct ftl_l2p_cache *cache = page->ctx.cache;
1240 	struct spdk_ftl_dev *dev = cache->dev;
1241 
1242 	ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io);
1243 	spdk_bdev_free_io(bdev_io);
1244 	page_in_io_complete(dev, cache, page, success);
1245 }
1246 
1247 static void
1248 page_in_io(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache, struct ftl_l2p_page *page)
1249 {
1250 	struct spdk_io_channel *ioch;
1251 	struct spdk_bdev *bdev;
1252 	struct spdk_bdev_io_wait_entry *bdev_io_wait;
1253 	int rc;
1254 	page->ctx.cache = cache;
1255 
1256 	rc = ftl_nv_cache_bdev_read_blocks_with_md(cache->dev, ftl_l2p_cache_get_bdev_desc(cache),
1257 			ftl_l2p_cache_get_bdev_iochannel(cache),
1258 			page->page_buffer, NULL, ftl_l2p_cache_page_get_bdev_offset(cache, page),
1259 			1, page_in_io_cb, page);
1260 	cache->ios_in_flight++;
1261 	if (spdk_likely(0 == rc)) {
1262 		return;
1263 	}
1264 
1265 	if (rc == -ENOMEM) {
1266 		ioch = ftl_l2p_cache_get_bdev_iochannel(cache);
1267 		bdev = spdk_bdev_desc_get_bdev(ftl_l2p_cache_get_bdev_desc(cache));
1268 		bdev_io_wait = &page->ctx.bdev_io_wait;
1269 		bdev_io_wait->bdev = bdev;
1270 		bdev_io_wait->cb_fn = page_in_io_retry;
1271 		bdev_io_wait->cb_arg = page;
1272 
1273 		rc = spdk_bdev_queue_io_wait(bdev, ioch, bdev_io_wait);
1274 		ftl_bug(rc);
1275 	} else {
1276 		ftl_abort();
1277 	}
1278 }
1279 
1280 static void
1281 page_in_io_retry(void *arg)
1282 {
1283 	struct ftl_l2p_page *page = arg;
1284 	struct ftl_l2p_cache *cache = page->ctx.cache;
1285 	struct spdk_ftl_dev *dev = cache->dev;
1286 
1287 	cache->ios_in_flight--;
1288 	page_in_io(dev, cache, page);
1289 }
1290 
1291 static void
1292 page_in(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache,
1293 	struct ftl_l2p_page_set *page_set, struct ftl_l2p_page_wait_ctx *pentry)
1294 {
1295 	struct ftl_l2p_page *page;
1296 	bool page_in = false;
1297 
1298 	/* Get page */
1299 	page = get_l2p_page_by_df_id(cache, pentry->pg_no);
1300 	if (!page) {
1301 		/* Page not allocated yet, do it */
1302 		page = page_allocate(cache, pentry->pg_no);
1303 		page_in = true;
1304 	}
1305 
1306 	if (ftl_l2p_cache_page_is_pinnable(page)) {
1307 		ftl_l2p_cache_page_pin(cache, page);
1308 		page_set->pinned_cnt++;
1309 		pentry->pg_pin_issued = true;
1310 		pentry->pg_pin_completed = true;
1311 	} else {
1312 		pentry->pg_pin_issued = true;
1313 		ftl_l2p_page_queue_wait_ctx(page, pentry);
1314 	}
1315 
1316 	if (page_in) {
1317 		page_in_io(dev, cache, page);
1318 	}
1319 }
1320 
1321 static int
1322 ftl_l2p_cache_process_page_sets(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache)
1323 {
1324 	struct ftl_l2p_page_set *page_set;
1325 	struct ftl_l2p_page_wait_ctx *pentry;
1326 	uint64_t i;
1327 
1328 	page_set = TAILQ_FIRST(&cache->deferred_page_set_list);
1329 	if (!page_set) {
1330 		/* No page_set */
1331 		return -ECHILD;
1332 	}
1333 
1334 	if (page_set->to_pin_cnt > cache->l2_pgs_avail) {
1335 		/* No enough page to pin, wait */
1336 		return -EBUSY;
1337 	}
1338 	if (cache->ios_in_flight > 512) {
1339 		/* Too big QD */
1340 		return -EBUSY;
1341 	}
1342 
1343 	ftl_add_io_activity(dev);
1344 
1345 	TAILQ_REMOVE(&cache->deferred_page_set_list, page_set, list_entry);
1346 	page_set->deferred = 0;
1347 	page_set->locked = 1;
1348 
1349 	/* Now we can start pinning */
1350 	pentry = page_set->entry;
1351 	for (i = 0; i < page_set->to_pin_cnt; i++, pentry++) {
1352 		if (!pentry->pg_pin_issued) {
1353 			page_in(dev, cache, page_set, pentry);
1354 		}
1355 	}
1356 
1357 	page_set->locked = 0;
1358 
1359 	/* Check if page_set is done */
1360 	if (page_set_is_done(page_set)) {
1361 		page_set_end(dev, cache, page_set);
1362 	}
1363 
1364 	return 0;
1365 }
1366 
1367 static struct ftl_l2p_page *
1368 eviction_get_page(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache)
1369 {
1370 	uint64_t i = 0;
1371 	struct ftl_l2p_page *page = ftl_l2p_cache_get_coldest_page(cache);
1372 
1373 	while (page) {
1374 		ftl_bug(L2P_CACHE_PAGE_READY != page->state);
1375 		ftl_bug(page->pin_ref_cnt);
1376 
1377 		if (ftl_l2p_cache_page_can_evict(page)) {
1378 			ftl_l2p_cache_lru_remove_page(cache, page);
1379 			return page;
1380 		}
1381 
1382 		/*
1383 		 * Practically only one iteration is needed to find a page. It is because
1384 		 * the rank of pages contains only ready and unpinned pages
1385 		 */
1386 		ftl_bug(++i > 1024);
1387 
1388 		page = ftl_l2p_cache_get_hotter_page(page);
1389 	}
1390 
1391 	return NULL;
1392 }
1393 
1394 static void
1395 page_out_io_complete(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache,
1396 		     struct ftl_l2p_page *page, bool success)
1397 {
1398 	cache->l2_pgs_evicting--;
1399 
1400 	ftl_bug(page->ctx.updates > page->updates);
1401 	ftl_bug(!TAILQ_EMPTY(&page->ppe_list));
1402 	ftl_bug(page->on_lru_list);
1403 
1404 	if (spdk_likely(success)) {
1405 		page->updates -= page->ctx.updates;
1406 	}
1407 
1408 	if (success && ftl_l2p_cache_page_can_remove(page)) {
1409 		ftl_l2p_cache_page_remove(cache, page);
1410 	} else {
1411 		if (!page->pin_ref_cnt) {
1412 			ftl_l2p_cache_lru_add_page(cache, page);
1413 		}
1414 		page->state = L2P_CACHE_PAGE_READY;
1415 	}
1416 }
1417 
1418 static void
1419 page_out_io_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
1420 {
1421 	struct ftl_l2p_page *page = cb_arg;
1422 	struct ftl_l2p_cache *cache = page->ctx.cache;
1423 	struct spdk_ftl_dev *dev = cache->dev;
1424 
1425 	ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io);
1426 	spdk_bdev_free_io(bdev_io);
1427 	page_out_io_complete(dev, cache, page, success);
1428 }
1429 
1430 static void
1431 page_out_io(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache,
1432 	    struct ftl_l2p_page *page)
1433 {
1434 	struct spdk_io_channel *ioch;
1435 	struct spdk_bdev *bdev;
1436 	struct spdk_bdev_io_wait_entry *bdev_io_wait;
1437 	int rc;
1438 
1439 	page->ctx.cache = cache;
1440 
1441 	rc = ftl_nv_cache_bdev_write_blocks_with_md(dev, ftl_l2p_cache_get_bdev_desc(cache),
1442 			ftl_l2p_cache_get_bdev_iochannel(cache),
1443 			page->page_buffer, NULL, ftl_l2p_cache_page_get_bdev_offset(cache, page),
1444 			1, page_out_io_cb, page);
1445 
1446 	cache->l2_pgs_evicting++;
1447 	if (spdk_likely(0 == rc)) {
1448 		return;
1449 	}
1450 
1451 	if (rc == -ENOMEM) {
1452 		ioch = ftl_l2p_cache_get_bdev_iochannel(cache);
1453 		bdev = spdk_bdev_desc_get_bdev(ftl_l2p_cache_get_bdev_desc(cache));
1454 		bdev_io_wait = &page->ctx.bdev_io_wait;
1455 		bdev_io_wait->bdev = bdev;
1456 		bdev_io_wait->cb_fn = page_out_io_retry;
1457 		bdev_io_wait->cb_arg = page;
1458 
1459 		rc = spdk_bdev_queue_io_wait(bdev, ioch, bdev_io_wait);
1460 		ftl_bug(rc);
1461 	} else {
1462 		ftl_abort();
1463 	}
1464 }
1465 
1466 static void
1467 page_out_io_retry(void *arg)
1468 {
1469 	struct ftl_l2p_page *page = arg;
1470 	struct ftl_l2p_cache *cache = page->ctx.cache;
1471 	struct spdk_ftl_dev *dev = cache->dev;
1472 
1473 	cache->l2_pgs_evicting--;
1474 	page_out_io(dev, cache, page);
1475 }
1476 
1477 static void
1478 ftl_l2p_cache_process_eviction(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache)
1479 {
1480 	struct ftl_l2p_page *page;
1481 
1482 	if (!ftl_l2p_cache_evict_continue(cache)) {
1483 		return;
1484 	}
1485 
1486 	if (cache->l2_pgs_evicting > 512) {
1487 		return;
1488 	}
1489 
1490 	ftl_add_io_activity(dev);
1491 
1492 	page = eviction_get_page(dev, cache);
1493 	if (spdk_unlikely(!page)) {
1494 		return;
1495 	}
1496 
1497 	if (page->updates) {
1498 		page->state = L2P_CACHE_PAGE_FLUSHING;
1499 		page->ctx.updates = page->updates;
1500 		page_out_io(dev, cache, page);
1501 	} else {
1502 		/* Page clean and we can remove it */
1503 		ftl_l2p_cache_page_remove(cache, page);
1504 	}
1505 }
1506 
1507 static void
1508 ftl_l2p_lazy_unmap_process_cb(struct spdk_ftl_dev *dev, int status, struct ftl_l2p_pin_ctx *pin_ctx)
1509 {
1510 	struct ftl_l2p_cache *cache = dev->l2p;
1511 
1512 	cache->lazy_unmap.qd--;
1513 
1514 	/* We will retry on next ftl_l2p_lazy_unmap_process */
1515 	if (spdk_unlikely(status != 0)) {
1516 		return;
1517 	}
1518 
1519 	if (ftl_l2p_cache_running(cache)) {
1520 		ftl_l2p_cache_get(dev, pin_ctx->lba);
1521 	}
1522 
1523 	ftl_l2p_cache_unpin(dev, pin_ctx->lba, pin_ctx->count);
1524 }
1525 
1526 static void
1527 ftl_l2p_lazy_unmap_process(struct spdk_ftl_dev *dev)
1528 {
1529 	struct ftl_l2p_cache *cache = dev->l2p;
1530 	struct ftl_l2p_pin_ctx *pin_ctx;
1531 	uint64_t page_no;
1532 
1533 	if (spdk_likely(!dev->unmap_in_progress)) {
1534 		return;
1535 	}
1536 
1537 	if (cache->lazy_unmap.qd == FTL_L2P_MAX_LAZY_UNMAP_QD) {
1538 		return;
1539 	}
1540 
1541 	page_no = ftl_bitmap_find_first_set(dev->unmap_map, cache->lazy_unmap.page_no, UINT64_MAX);
1542 	if (page_no == UINT64_MAX) {
1543 		cache->lazy_unmap.page_no = 0;
1544 
1545 		/* Check unmap map from beginning to detect unprocessed unmaps */
1546 		page_no = ftl_bitmap_find_first_set(dev->unmap_map, cache->lazy_unmap.page_no, UINT64_MAX);
1547 		if (page_no == UINT64_MAX) {
1548 			dev->unmap_in_progress = false;
1549 			return;
1550 		}
1551 	}
1552 
1553 	cache->lazy_unmap.page_no = page_no;
1554 
1555 	pin_ctx = &cache->lazy_unmap.pin_ctx;
1556 
1557 	cache->lazy_unmap.qd++;
1558 	assert(cache->lazy_unmap.qd <= FTL_L2P_MAX_LAZY_UNMAP_QD);
1559 	assert(page_no < cache->num_pages);
1560 
1561 	pin_ctx->lba = page_no * cache->lbas_in_page;
1562 	pin_ctx->count = 1;
1563 	pin_ctx->cb = ftl_l2p_lazy_unmap_process_cb;
1564 	pin_ctx->cb_ctx = pin_ctx;
1565 
1566 	ftl_l2p_cache_pin(dev, pin_ctx);
1567 }
1568 
1569 void
1570 ftl_l2p_cache_process(struct spdk_ftl_dev *dev)
1571 {
1572 	struct ftl_l2p_cache *cache = dev->l2p;
1573 	int i;
1574 
1575 	if (spdk_unlikely(cache->state != L2P_CACHE_RUNNING)) {
1576 		return;
1577 	}
1578 
1579 	for (i = 0; i < 256; i++) {
1580 		if (ftl_l2p_cache_process_page_sets(dev, cache)) {
1581 			break;
1582 		}
1583 	}
1584 
1585 	ftl_l2p_cache_process_eviction(dev, cache);
1586 	ftl_l2p_lazy_unmap_process(dev);
1587 }
1588