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