1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 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 backgorund */ 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 cache->state = L2P_CACHE_RUNNING; 508 return 0; 509 } 510 511 static void 512 ftl_l2p_cache_deinit_l2(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache) 513 { 514 ftl_md_destroy(cache->l2_ctx_md, ftl_md_destroy_shm_flags(dev)); 515 cache->l2_ctx_md = NULL; 516 517 ftl_mempool_destroy_ext(cache->l2_ctx_pool); 518 cache->l2_ctx_pool = NULL; 519 520 ftl_md_destroy(cache->l1_md, ftl_md_destroy_shm_flags(dev)); 521 cache->l1_md = NULL; 522 523 ftl_mempool_destroy(cache->page_sets_pool); 524 cache->page_sets_pool = NULL; 525 } 526 527 static void 528 _ftl_l2p_cache_deinit(struct spdk_ftl_dev *dev) 529 { 530 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 531 532 ftl_l2p_cache_deinit_l2(dev, cache); 533 ftl_md_destroy(cache->l2_md, ftl_md_destroy_shm_flags(dev)); 534 free(cache); 535 } 536 537 void 538 ftl_l2p_cache_deinit(struct spdk_ftl_dev *dev) 539 { 540 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 541 542 if (!cache) { 543 return; 544 } 545 assert(cache->state == L2P_CACHE_SHUTDOWN_DONE || cache->state == L2P_CACHE_INIT); 546 547 _ftl_l2p_cache_deinit(dev); 548 dev->l2p = 0; 549 } 550 551 static void 552 process_init_ctx(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache, 553 ftl_l2p_cb cb, void *cb_ctx) 554 { 555 struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx; 556 557 assert(NULL == ctx->cb_ctx); 558 assert(0 == cache->l2_pgs_evicting); 559 560 memset(ctx, 0, sizeof(*ctx)); 561 562 ctx->cb = cb; 563 ctx->cb_ctx = cb_ctx; 564 } 565 566 static void 567 process_finish(struct ftl_l2p_cache *cache) 568 { 569 struct ftl_l2p_cache_process_ctx ctx = cache->mctx; 570 571 assert(cache->l2_pgs_avail == cache->l2_pgs_resident_max); 572 assert(0 == ctx.qd); 573 574 memset(&cache->mctx, 0, sizeof(cache->mctx)); 575 ctx.cb(cache->dev, ctx.status, ctx.cb_ctx); 576 } 577 578 static void process_page_out_retry(void *_page); 579 static void process_persist(struct ftl_l2p_cache *cache); 580 581 static void 582 process_page_in(struct ftl_l2p_page *page, spdk_bdev_io_completion_cb cb) 583 { 584 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)page->ctx.cache; 585 int rc; 586 587 assert(page->page_buffer); 588 589 rc = ftl_nv_cache_bdev_read_blocks_with_md(cache->dev, ftl_l2p_cache_get_bdev_desc(cache), 590 ftl_l2p_cache_get_bdev_iochannel(cache), 591 page->page_buffer, NULL, ftl_l2p_cache_page_get_bdev_offset(cache, page), 592 1, cb, page); 593 594 if (rc) { 595 cb(NULL, false, page); 596 } 597 } 598 599 static void 600 process_persist_page_out_cb(struct spdk_bdev_io *bdev_io, bool success, void *arg) 601 { 602 struct ftl_l2p_page *page = arg; 603 struct ftl_l2p_cache *cache = page->ctx.cache; 604 struct spdk_ftl_dev *dev = cache->dev; 605 struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx; 606 607 assert(bdev_io); 608 ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io); 609 spdk_bdev_free_io(bdev_io); 610 611 if (!success) { 612 ctx->status = -EIO; 613 } 614 615 if (ftl_bitmap_get(dev->unmap_map, ctx->idx)) { 616 /* 617 * Page had been unmapped, in persist path before IO, it was invalidated entirely 618 * now clear unmap flag 619 */ 620 ftl_bitmap_clear(dev->unmap_map, page->page_no); 621 } 622 ftl_l2p_cache_page_remove(cache, page); 623 624 ctx->qd--; 625 process_persist(cache); 626 } 627 628 static void 629 process_page_out(struct ftl_l2p_page *page, spdk_bdev_io_completion_cb cb) 630 { 631 struct spdk_bdev *bdev; 632 struct spdk_bdev_io_wait_entry *bdev_io_wait; 633 struct ftl_l2p_cache *cache = page->ctx.cache; 634 struct spdk_ftl_dev *dev = cache->dev; 635 int rc; 636 637 assert(page->page_buffer); 638 639 rc = ftl_nv_cache_bdev_write_blocks_with_md(dev, ftl_l2p_cache_get_bdev_desc(cache), 640 ftl_l2p_cache_get_bdev_iochannel(cache), 641 page->page_buffer, NULL, ftl_l2p_cache_page_get_bdev_offset(cache, page), 642 1, cb, page); 643 644 if (spdk_likely(0 == rc)) { 645 return; 646 } 647 648 if (rc == -ENOMEM) { 649 bdev = spdk_bdev_desc_get_bdev(ftl_l2p_cache_get_bdev_desc(cache)); 650 bdev_io_wait = &page->ctx.bdev_io_wait; 651 bdev_io_wait->bdev = bdev; 652 bdev_io_wait->cb_fn = process_page_out_retry; 653 bdev_io_wait->cb_arg = page; 654 page->ctx.cb = cb; 655 656 rc = spdk_bdev_queue_io_wait(bdev, ftl_l2p_cache_get_bdev_iochannel(cache), bdev_io_wait); 657 ftl_bug(rc); 658 } else { 659 ftl_abort(); 660 } 661 } 662 663 static void 664 process_page_out_retry(void *_page) 665 { 666 struct ftl_l2p_page *page = _page; 667 668 process_page_out(page, page->ctx.cb); 669 } 670 671 static void process_unmap(struct ftl_l2p_cache *cache); 672 673 static void 674 process_unmap_page_out_cb(struct spdk_bdev_io *bdev_io, bool success, void *ctx_page) 675 { 676 struct ftl_l2p_page *page = (struct ftl_l2p_page *)ctx_page; 677 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)page->ctx.cache; 678 struct spdk_ftl_dev *dev = cache->dev; 679 struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx; 680 681 assert(bdev_io); 682 ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io); 683 spdk_bdev_free_io(bdev_io); 684 685 if (!success) { 686 ctx->status = -EIO; 687 } 688 689 assert(!page->on_lru_list); 690 assert(ftl_bitmap_get(dev->unmap_map, page->page_no)); 691 ftl_bitmap_clear(dev->unmap_map, page->page_no); 692 ftl_l2p_cache_page_remove(cache, page); 693 694 ctx->qd--; 695 process_unmap(cache); 696 } 697 698 static void 699 process_unmap_page_in_cb(struct spdk_bdev_io *bdev_io, bool success, void *ctx_page) 700 { 701 struct ftl_l2p_page *page = (struct ftl_l2p_page *)ctx_page; 702 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)page->ctx.cache; 703 struct spdk_ftl_dev *dev = cache->dev; 704 struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx; 705 706 if (bdev_io) { 707 ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io); 708 spdk_bdev_free_io(bdev_io); 709 } 710 if (success) { 711 assert(ftl_bitmap_get(dev->unmap_map, page->page_no)); 712 ftl_l2p_page_set_invalid(dev, page); 713 process_page_out(page, process_unmap_page_out_cb); 714 } else { 715 ctx->status = -EIO; 716 ctx->qd--; 717 process_unmap(cache); 718 } 719 } 720 721 static void 722 process_unmap(struct ftl_l2p_cache *cache) 723 { 724 struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx; 725 726 while (ctx->idx < cache->num_pages && ctx->qd < 64) { 727 struct ftl_l2p_page *page; 728 729 if (!ftl_bitmap_get(cache->dev->unmap_map, ctx->idx)) { 730 /* Page had not been unmapped, continue */ 731 ctx->idx++; 732 continue; 733 } 734 735 /* All pages were removed in persist phase */ 736 assert(get_l2p_page_by_df_id(cache, ctx->idx) == NULL); 737 738 /* Allocate page to invalidate it */ 739 page = ftl_l2p_cache_page_alloc(cache, ctx->idx); 740 if (!page) { 741 /* All pages utilized so far, continue when they will be back available */ 742 assert(ctx->qd); 743 break; 744 } 745 746 page->state = L2P_CACHE_PAGE_CLEARING; 747 page->ctx.cache = cache; 748 749 ftl_l2p_cache_page_insert(cache, page); 750 process_page_in(page, process_unmap_page_in_cb); 751 752 ctx->qd++; 753 ctx->idx++; 754 } 755 756 if (0 == ctx->qd) { 757 process_finish(cache); 758 } 759 } 760 761 void 762 ftl_l2p_cache_unmap(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx) 763 { 764 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 765 766 process_init_ctx(dev, cache, cb, cb_ctx); 767 process_unmap(cache); 768 } 769 770 static void 771 clear_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status) 772 { 773 ftl_l2p_cb cb = md->owner.private; 774 void *cb_cntx = md->owner.cb_ctx; 775 776 cb(dev, status, cb_cntx); 777 } 778 779 void 780 ftl_l2p_cache_clear(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx) 781 { 782 struct ftl_md *md = dev->layout.md[FTL_LAYOUT_REGION_TYPE_L2P]; 783 ftl_addr invalid_addr = FTL_ADDR_INVALID; 784 785 md->cb = clear_cb; 786 md->owner.cb_ctx = cb_ctx; 787 md->owner.private = cb; 788 789 ftl_md_clear(md, invalid_addr, NULL); 790 } 791 792 static void 793 l2p_shm_restore_clean(struct spdk_ftl_dev *dev) 794 { 795 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 796 struct ftl_l2p_l1_map_entry *me = cache->l2_mapping; 797 struct ftl_l2p_page *page; 798 ftl_df_obj_id obj_id; 799 uint64_t page_no; 800 801 for (page_no = 0; page_no < cache->num_pages; ++page_no) { 802 obj_id = me[page_no].page_obj_id; 803 if (obj_id == FTL_DF_OBJ_ID_INVALID) { 804 continue; 805 } 806 807 page = ftl_mempool_claim_df(cache->l2_ctx_pool, obj_id); 808 assert(page); 809 assert(page->obj_id == ftl_mempool_get_df_obj_id(cache->l2_ctx_pool, page)); 810 assert(page->page_no == page_no); 811 assert(page->state != L2P_CACHE_PAGE_INIT); 812 assert(page->state != L2P_CACHE_PAGE_CLEARING); 813 assert(cache->l2_pgs_avail > 0); 814 cache->l2_pgs_avail--; 815 816 page->page_buffer = (char *)ftl_md_get_buffer(cache->l1_md) + ftl_mempool_get_df_obj_index( 817 cache->l2_ctx_pool, page) * FTL_BLOCK_SIZE; 818 819 TAILQ_INIT(&page->ppe_list); 820 821 page->pin_ref_cnt = 0; 822 page->on_lru_list = 0; 823 memset(&page->ctx, 0, sizeof(page->ctx)); 824 825 ftl_l2p_cache_lru_add_page(cache, page); 826 } 827 828 ftl_mempool_initialize_ext(cache->l2_ctx_pool); 829 } 830 831 static void 832 l2p_shm_restore_dirty(struct spdk_ftl_dev *dev) 833 { 834 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 835 struct ftl_l2p_l1_map_entry *me = cache->l2_mapping; 836 struct ftl_l2p_page *page; 837 ftl_df_obj_id obj_id; 838 uint64_t page_no; 839 840 for (page_no = 0; page_no < cache->num_pages; ++page_no) { 841 obj_id = me[page_no].page_obj_id; 842 if (obj_id == FTL_DF_OBJ_ID_INVALID) { 843 continue; 844 } 845 846 page = ftl_mempool_claim_df(cache->l2_ctx_pool, obj_id); 847 assert(page); 848 assert(page->obj_id == ftl_mempool_get_df_obj_id(cache->l2_ctx_pool, page)); 849 assert(page->page_no == page_no); 850 assert(page->state != L2P_CACHE_PAGE_CLEARING); 851 assert(cache->l2_pgs_avail > 0); 852 cache->l2_pgs_avail--; 853 854 if (page->state == L2P_CACHE_PAGE_INIT) { 855 me[page_no].page_obj_id = FTL_DF_OBJ_ID_INVALID; 856 cache->l2_pgs_avail++; 857 ftl_mempool_release_df(cache->l2_ctx_pool, obj_id); 858 continue; 859 } 860 861 page->state = L2P_CACHE_PAGE_READY; 862 /* Assume page is dirty after crash */ 863 page->updates = 1; 864 page->page_buffer = (char *)ftl_md_get_buffer(cache->l1_md) + ftl_mempool_get_df_obj_index( 865 cache->l2_ctx_pool, page) * FTL_BLOCK_SIZE; 866 867 TAILQ_INIT(&page->ppe_list); 868 869 page->pin_ref_cnt = 0; 870 page->on_lru_list = 0; 871 memset(&page->ctx, 0, sizeof(page->ctx)); 872 873 ftl_l2p_cache_lru_add_page(cache, page); 874 } 875 876 ftl_mempool_initialize_ext(cache->l2_ctx_pool); 877 } 878 879 void 880 ftl_l2p_cache_restore(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx) 881 { 882 if (ftl_fast_startup(dev)) { 883 l2p_shm_restore_clean(dev); 884 } 885 886 if (ftl_fast_recovery(dev)) { 887 l2p_shm_restore_dirty(dev); 888 } 889 890 cb(dev, 0, cb_ctx); 891 } 892 893 static void 894 process_persist(struct ftl_l2p_cache *cache) 895 { 896 struct ftl_l2p_cache_process_ctx *ctx = &cache->mctx; 897 struct spdk_ftl_dev *dev = cache->dev; 898 899 while (ctx->idx < cache->num_pages && ctx->qd < 64) { 900 struct ftl_l2p_page *page = get_l2p_page_by_df_id(cache, ctx->idx); 901 ctx->idx++; 902 903 if (!page) { 904 continue; 905 } 906 907 /* Finished unmap if the page was marked */ 908 if (ftl_bitmap_get(dev->unmap_map, ctx->idx)) { 909 ftl_l2p_page_set_invalid(dev, page); 910 } 911 912 if (page->on_lru_list) { 913 ftl_l2p_cache_lru_remove_page(cache, page); 914 } 915 916 if (page->updates) { 917 /* Need to persist the page */ 918 page->state = L2P_CACHE_PAGE_PERSISTING; 919 page->ctx.cache = cache; 920 ctx->qd++; 921 process_page_out(page, process_persist_page_out_cb); 922 } else { 923 ftl_l2p_cache_page_remove(cache, page); 924 } 925 } 926 927 if (0 == ctx->qd) { 928 process_finish(cache); 929 } 930 } 931 932 void 933 ftl_l2p_cache_persist(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx) 934 { 935 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 936 937 process_init_ctx(dev, cache, cb, cb_ctx); 938 process_persist(cache); 939 } 940 941 bool 942 ftl_l2p_cache_is_halted(struct spdk_ftl_dev *dev) 943 { 944 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 945 946 return cache->state == L2P_CACHE_SHUTDOWN_DONE; 947 } 948 949 void 950 ftl_l2p_cache_halt(struct spdk_ftl_dev *dev) 951 { 952 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 953 954 if (cache->state != L2P_CACHE_SHUTDOWN_DONE) { 955 cache->state = L2P_CACHE_IN_SHUTDOWN; 956 if (!cache->ios_in_flight && !cache->l2_pgs_evicting) { 957 cache->state = L2P_CACHE_SHUTDOWN_DONE; 958 } 959 } 960 } 961 962 static inline struct ftl_l2p_page * 963 get_page(struct ftl_l2p_cache *cache, uint64_t lba) 964 { 965 return get_l2p_page_by_df_id(cache, lba / cache->lbas_in_page); 966 } 967 968 static inline void 969 ftl_l2p_cache_init_page_set(struct ftl_l2p_page_set *page_set, struct ftl_l2p_pin_ctx *pin_ctx) 970 { 971 page_set->to_pin_cnt = 0; 972 page_set->pinned_cnt = 0; 973 page_set->pin_fault_cnt = 0; 974 page_set->locked = 0; 975 page_set->deferred = 0; 976 page_set->pin_ctx = pin_ctx; 977 } 978 979 static inline bool 980 ftl_l2p_cache_running(struct ftl_l2p_cache *cache) 981 { 982 return cache->state == L2P_CACHE_RUNNING; 983 } 984 985 static inline bool 986 ftl_l2p_cache_page_is_pinnable(struct ftl_l2p_page *page) 987 { 988 return page->state != L2P_CACHE_PAGE_INIT; 989 } 990 991 void 992 ftl_l2p_cache_pin(struct spdk_ftl_dev *dev, struct ftl_l2p_pin_ctx *pin_ctx) 993 { 994 assert(dev->num_lbas >= pin_ctx->lba + pin_ctx->count); 995 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 996 struct ftl_l2p_page_set *page_set; 997 bool defer_pin = false; 998 999 /* Calculate first and last page to pin, count of them */ 1000 uint64_t start = pin_ctx->lba / cache->lbas_in_page; 1001 uint64_t end = (pin_ctx->lba + pin_ctx->count - 1) / cache->lbas_in_page; 1002 uint64_t count = end - start + 1; 1003 uint64_t i; 1004 1005 if (spdk_unlikely(count > L2P_MAX_PAGES_TO_PIN)) { 1006 ftl_l2p_pin_complete(dev, -E2BIG, pin_ctx); 1007 return; 1008 } 1009 1010 /* Get and initialize page sets */ 1011 assert(ftl_l2p_cache_running(cache)); 1012 page_set = ftl_mempool_get(cache->page_sets_pool); 1013 if (!page_set) { 1014 ftl_l2p_pin_complete(dev, -EAGAIN, pin_ctx); 1015 return; 1016 } 1017 ftl_l2p_cache_init_page_set(page_set, pin_ctx); 1018 1019 struct ftl_l2p_page_wait_ctx *entry = page_set->entry; 1020 for (i = start; i <= end; i++, entry++) { 1021 struct ftl_l2p_page *page; 1022 entry->parent = page_set; 1023 entry->pg_no = i; 1024 entry->pg_pin_completed = false; 1025 entry->pg_pin_issued = false; 1026 1027 page_set->to_pin_cnt++; 1028 1029 /* Try get page and pin */ 1030 page = get_l2p_page_by_df_id(cache, i); 1031 if (page) { 1032 if (ftl_l2p_cache_page_is_pinnable(page)) { 1033 /* Page available and we can pin it */ 1034 page_set->pinned_cnt++; 1035 entry->pg_pin_issued = true; 1036 entry->pg_pin_completed = true; 1037 ftl_l2p_cache_page_pin(cache, page); 1038 } else { 1039 /* The page is being loaded */ 1040 /* Queue the page pin entry to be executed on page in */ 1041 ftl_l2p_page_queue_wait_ctx(page, entry); 1042 entry->pg_pin_issued = true; 1043 } 1044 } else { 1045 /* The page is not in the cache, queue the page_set to page in */ 1046 defer_pin = true; 1047 } 1048 } 1049 1050 /* Check if page set is done */ 1051 if (page_set_is_done(page_set)) { 1052 page_set_end(dev, cache, page_set); 1053 } else if (defer_pin) { 1054 TAILQ_INSERT_TAIL(&cache->deferred_page_set_list, page_set, list_entry); 1055 page_set->deferred = 1; 1056 } 1057 } 1058 1059 void 1060 ftl_l2p_cache_unpin(struct spdk_ftl_dev *dev, uint64_t lba, uint64_t count) 1061 { 1062 assert(dev->num_lbas >= lba + count); 1063 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 1064 struct ftl_l2p_page *page; 1065 uint64_t start = lba / cache->lbas_in_page; 1066 uint64_t end = (lba + count - 1) / cache->lbas_in_page; 1067 uint64_t i; 1068 1069 assert(count); 1070 assert(start < cache->num_pages); 1071 assert(end < cache->num_pages); 1072 1073 for (i = start; i <= end; i++) { 1074 page = get_l2p_page_by_df_id(cache, i); 1075 ftl_bug(!page); 1076 ftl_l2p_cache_page_unpin(cache, page); 1077 } 1078 } 1079 1080 ftl_addr 1081 ftl_l2p_cache_get(struct spdk_ftl_dev *dev, uint64_t lba) 1082 { 1083 assert(dev->num_lbas > lba); 1084 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 1085 struct ftl_l2p_page *page = get_page(cache, lba); 1086 ftl_addr addr; 1087 1088 ftl_bug(!page); 1089 assert(ftl_l2p_cache_running(cache)); 1090 assert(page->pin_ref_cnt); 1091 1092 if (ftl_bitmap_get(dev->unmap_map, page->page_no)) { 1093 ftl_l2p_page_set_invalid(dev, page); 1094 ftl_bitmap_clear(dev->unmap_map, page->page_no); 1095 } 1096 1097 ftl_l2p_cache_lru_promote_page(cache, page); 1098 addr = ftl_l2p_cache_get_addr(dev, cache, page, lba); 1099 1100 return addr; 1101 } 1102 1103 void 1104 ftl_l2p_cache_set(struct spdk_ftl_dev *dev, uint64_t lba, ftl_addr addr) 1105 { 1106 assert(dev->num_lbas > lba); 1107 struct ftl_l2p_cache *cache = (struct ftl_l2p_cache *)dev->l2p; 1108 struct ftl_l2p_page *page = get_page(cache, lba); 1109 1110 ftl_bug(!page); 1111 assert(ftl_l2p_cache_running(cache)); 1112 assert(page->pin_ref_cnt); 1113 1114 if (ftl_bitmap_get(dev->unmap_map, page->page_no)) { 1115 ftl_l2p_page_set_invalid(dev, page); 1116 ftl_bitmap_clear(dev->unmap_map, page->page_no); 1117 } 1118 1119 page->updates++; 1120 ftl_l2p_cache_lru_promote_page(cache, page); 1121 ftl_l2p_cache_set_addr(dev, cache, page, lba, addr); 1122 } 1123 1124 static struct ftl_l2p_page * 1125 page_allocate(struct ftl_l2p_cache *cache, uint64_t page_no) 1126 { 1127 struct ftl_l2p_page *page = ftl_l2p_cache_page_alloc(cache, page_no); 1128 ftl_l2p_cache_page_insert(cache, page); 1129 1130 return page; 1131 } 1132 1133 static bool 1134 page_set_is_done(struct ftl_l2p_page_set *page_set) 1135 { 1136 if (page_set->locked) { 1137 return false; 1138 } 1139 1140 assert(page_set->pinned_cnt + page_set->pin_fault_cnt <= page_set->to_pin_cnt); 1141 return (page_set->pinned_cnt + page_set->pin_fault_cnt == page_set->to_pin_cnt); 1142 } 1143 1144 static void 1145 page_set_unpin(struct ftl_l2p_cache *cache, struct ftl_l2p_page_set *page_set) 1146 { 1147 uint64_t i; 1148 struct ftl_l2p_page_wait_ctx *pentry = page_set->entry; 1149 1150 for (i = 0; i < page_set->to_pin_cnt; i++, pentry++) { 1151 struct ftl_l2p_page *pinned_page; 1152 1153 if (false == pentry->pg_pin_completed) { 1154 continue; 1155 } 1156 1157 pinned_page = get_l2p_page_by_df_id(cache, pentry->pg_no); 1158 ftl_bug(!pinned_page); 1159 1160 ftl_l2p_cache_page_unpin(cache, pinned_page); 1161 } 1162 } 1163 1164 static void 1165 page_set_end(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache, 1166 struct ftl_l2p_page_set *page_set) 1167 { 1168 if (spdk_likely(0 == page_set->pin_fault_cnt)) { 1169 ftl_l2p_pin_complete(dev, 0, page_set->pin_ctx); 1170 } else { 1171 page_set_unpin(cache, page_set); 1172 ftl_l2p_pin_complete(dev, -EIO, page_set->pin_ctx); 1173 } 1174 1175 if (page_set->deferred) { 1176 TAILQ_REMOVE(&cache->deferred_page_set_list, page_set, list_entry); 1177 } 1178 1179 assert(0 == page_set->locked); 1180 ftl_mempool_put(cache->page_sets_pool, page_set); 1181 } 1182 1183 static void 1184 page_in_io_complete(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache, 1185 struct ftl_l2p_page *page, bool success) 1186 { 1187 struct ftl_l2p_page_set *page_set; 1188 struct ftl_l2p_page_wait_ctx *pentry; 1189 1190 cache->ios_in_flight--; 1191 1192 assert(0 == page->pin_ref_cnt); 1193 assert(L2P_CACHE_PAGE_INIT == page->state); 1194 assert(false == page->on_lru_list); 1195 1196 if (spdk_likely(success)) { 1197 page->state = L2P_CACHE_PAGE_READY; 1198 } 1199 1200 while ((pentry = TAILQ_FIRST(&page->ppe_list))) { 1201 TAILQ_REMOVE(&page->ppe_list, pentry, list_entry); 1202 1203 page_set = pentry->parent; 1204 1205 assert(false == pentry->pg_pin_completed); 1206 1207 if (success) { 1208 ftl_l2p_cache_page_pin(cache, page); 1209 page_set->pinned_cnt++; 1210 pentry->pg_pin_completed = true; 1211 } else { 1212 page_set->pin_fault_cnt++; 1213 } 1214 1215 /* Check if page_set is done */ 1216 if (page_set_is_done(page_set)) { 1217 page_set_end(dev, cache, page_set); 1218 } 1219 } 1220 1221 if (spdk_unlikely(!success)) { 1222 ftl_bug(page->on_lru_list); 1223 ftl_l2p_cache_page_remove(cache, page); 1224 } 1225 } 1226 1227 static void 1228 page_in_io_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 1229 { 1230 struct ftl_l2p_page *page = cb_arg; 1231 struct ftl_l2p_cache *cache = page->ctx.cache; 1232 struct spdk_ftl_dev *dev = cache->dev; 1233 1234 ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io); 1235 spdk_bdev_free_io(bdev_io); 1236 page_in_io_complete(dev, cache, page, success); 1237 } 1238 1239 static void 1240 page_in_io(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache, struct ftl_l2p_page *page) 1241 { 1242 struct spdk_io_channel *ioch; 1243 struct spdk_bdev *bdev; 1244 struct spdk_bdev_io_wait_entry *bdev_io_wait; 1245 int rc; 1246 page->ctx.cache = cache; 1247 1248 rc = ftl_nv_cache_bdev_read_blocks_with_md(cache->dev, ftl_l2p_cache_get_bdev_desc(cache), 1249 ftl_l2p_cache_get_bdev_iochannel(cache), 1250 page->page_buffer, NULL, ftl_l2p_cache_page_get_bdev_offset(cache, page), 1251 1, page_in_io_cb, page); 1252 cache->ios_in_flight++; 1253 if (spdk_likely(0 == rc)) { 1254 return; 1255 } 1256 1257 if (rc == -ENOMEM) { 1258 ioch = ftl_l2p_cache_get_bdev_iochannel(cache); 1259 bdev = spdk_bdev_desc_get_bdev(ftl_l2p_cache_get_bdev_desc(cache)); 1260 bdev_io_wait = &page->ctx.bdev_io_wait; 1261 bdev_io_wait->bdev = bdev; 1262 bdev_io_wait->cb_fn = page_in_io_retry; 1263 bdev_io_wait->cb_arg = page; 1264 1265 rc = spdk_bdev_queue_io_wait(bdev, ioch, bdev_io_wait); 1266 ftl_bug(rc); 1267 } else { 1268 ftl_abort(); 1269 } 1270 } 1271 1272 static void 1273 page_in_io_retry(void *arg) 1274 { 1275 struct ftl_l2p_page *page = arg; 1276 struct ftl_l2p_cache *cache = page->ctx.cache; 1277 struct spdk_ftl_dev *dev = cache->dev; 1278 1279 cache->ios_in_flight--; 1280 page_in_io(dev, cache, page); 1281 } 1282 1283 static void 1284 page_in(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache, 1285 struct ftl_l2p_page_set *page_set, struct ftl_l2p_page_wait_ctx *pentry) 1286 { 1287 struct ftl_l2p_page *page; 1288 bool page_in = false; 1289 1290 /* Get page */ 1291 page = get_l2p_page_by_df_id(cache, pentry->pg_no); 1292 if (!page) { 1293 /* Page not allocated yet, do it */ 1294 page = page_allocate(cache, pentry->pg_no); 1295 page_in = true; 1296 } 1297 1298 if (ftl_l2p_cache_page_is_pinnable(page)) { 1299 ftl_l2p_cache_page_pin(cache, page); 1300 page_set->pinned_cnt++; 1301 pentry->pg_pin_issued = true; 1302 pentry->pg_pin_completed = true; 1303 } else { 1304 pentry->pg_pin_issued = true; 1305 ftl_l2p_page_queue_wait_ctx(page, pentry); 1306 } 1307 1308 if (page_in) { 1309 page_in_io(dev, cache, page); 1310 } 1311 } 1312 1313 static int 1314 ftl_l2p_cache_process_page_sets(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache) 1315 { 1316 struct ftl_l2p_page_set *page_set; 1317 struct ftl_l2p_page_wait_ctx *pentry; 1318 uint64_t i; 1319 1320 page_set = TAILQ_FIRST(&cache->deferred_page_set_list); 1321 if (!page_set) { 1322 /* No page_set */ 1323 return -ECHILD; 1324 } 1325 1326 if (page_set->to_pin_cnt > cache->l2_pgs_avail) { 1327 /* No enough page to pin, wait */ 1328 return -EBUSY; 1329 } 1330 if (cache->ios_in_flight > 512) { 1331 /* Too big QD */ 1332 return -EBUSY; 1333 } 1334 1335 TAILQ_REMOVE(&cache->deferred_page_set_list, page_set, list_entry); 1336 page_set->deferred = 0; 1337 page_set->locked = 1; 1338 1339 /* Now we can start pinning */ 1340 pentry = page_set->entry; 1341 for (i = 0; i < page_set->to_pin_cnt; i++, pentry++) { 1342 if (!pentry->pg_pin_issued) { 1343 page_in(dev, cache, page_set, pentry); 1344 } 1345 } 1346 1347 page_set->locked = 0; 1348 1349 /* Check if page_set is done */ 1350 if (page_set_is_done(page_set)) { 1351 page_set_end(dev, cache, page_set); 1352 } 1353 1354 return 0; 1355 } 1356 1357 static struct ftl_l2p_page * 1358 eviction_get_page(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache) 1359 { 1360 uint64_t i = 0; 1361 struct ftl_l2p_page *page = ftl_l2p_cache_get_coldest_page(cache); 1362 1363 while (page) { 1364 ftl_bug(L2P_CACHE_PAGE_READY != page->state); 1365 ftl_bug(page->pin_ref_cnt); 1366 1367 if (ftl_l2p_cache_page_can_evict(page)) { 1368 ftl_l2p_cache_lru_remove_page(cache, page); 1369 return page; 1370 } 1371 1372 /* 1373 * Practically only one iteration is needed to find a page. It is because 1374 * the rank of pages contains only ready and unpinned pages 1375 */ 1376 ftl_bug(++i > 1024); 1377 1378 page = ftl_l2p_cache_get_hotter_page(page); 1379 } 1380 1381 return NULL; 1382 } 1383 1384 static void 1385 page_out_io_complete(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache, 1386 struct ftl_l2p_page *page, bool success) 1387 { 1388 cache->l2_pgs_evicting--; 1389 1390 ftl_bug(page->ctx.updates > page->updates); 1391 ftl_bug(!TAILQ_EMPTY(&page->ppe_list)); 1392 ftl_bug(page->on_lru_list); 1393 1394 if (spdk_likely(success)) { 1395 page->updates -= page->ctx.updates; 1396 } 1397 1398 if (success && ftl_l2p_cache_page_can_remove(page)) { 1399 ftl_l2p_cache_page_remove(cache, page); 1400 } else { 1401 if (!page->pin_ref_cnt) { 1402 ftl_l2p_cache_lru_add_page(cache, page); 1403 } 1404 page->state = L2P_CACHE_PAGE_READY; 1405 } 1406 } 1407 1408 static void 1409 page_out_io_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 1410 { 1411 struct ftl_l2p_page *page = cb_arg; 1412 struct ftl_l2p_cache *cache = page->ctx.cache; 1413 struct spdk_ftl_dev *dev = cache->dev; 1414 1415 ftl_stats_bdev_io_completed(dev, FTL_STATS_TYPE_L2P, bdev_io); 1416 spdk_bdev_free_io(bdev_io); 1417 page_out_io_complete(dev, cache, page, success); 1418 } 1419 1420 static void 1421 page_out_io(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache, 1422 struct ftl_l2p_page *page) 1423 { 1424 struct spdk_io_channel *ioch; 1425 struct spdk_bdev *bdev; 1426 struct spdk_bdev_io_wait_entry *bdev_io_wait; 1427 int rc; 1428 1429 page->ctx.cache = cache; 1430 1431 rc = ftl_nv_cache_bdev_write_blocks_with_md(dev, ftl_l2p_cache_get_bdev_desc(cache), 1432 ftl_l2p_cache_get_bdev_iochannel(cache), 1433 page->page_buffer, NULL, ftl_l2p_cache_page_get_bdev_offset(cache, page), 1434 1, page_out_io_cb, page); 1435 1436 cache->l2_pgs_evicting++; 1437 if (spdk_likely(0 == rc)) { 1438 return; 1439 } 1440 1441 if (rc == -ENOMEM) { 1442 ioch = ftl_l2p_cache_get_bdev_iochannel(cache); 1443 bdev = spdk_bdev_desc_get_bdev(ftl_l2p_cache_get_bdev_desc(cache)); 1444 bdev_io_wait = &page->ctx.bdev_io_wait; 1445 bdev_io_wait->bdev = bdev; 1446 bdev_io_wait->cb_fn = page_out_io_retry; 1447 bdev_io_wait->cb_arg = page; 1448 1449 rc = spdk_bdev_queue_io_wait(bdev, ioch, bdev_io_wait); 1450 ftl_bug(rc); 1451 } else { 1452 ftl_abort(); 1453 } 1454 } 1455 1456 static void 1457 page_out_io_retry(void *arg) 1458 { 1459 struct ftl_l2p_page *page = arg; 1460 struct ftl_l2p_cache *cache = page->ctx.cache; 1461 struct spdk_ftl_dev *dev = cache->dev; 1462 1463 cache->l2_pgs_evicting--; 1464 page_out_io(dev, cache, page); 1465 } 1466 1467 static void 1468 ftl_l2p_cache_process_eviction(struct spdk_ftl_dev *dev, struct ftl_l2p_cache *cache) 1469 { 1470 struct ftl_l2p_page *page; 1471 1472 if (!ftl_l2p_cache_evict_continue(cache)) { 1473 return; 1474 } 1475 1476 if (cache->l2_pgs_evicting > 512) { 1477 return; 1478 } 1479 1480 page = eviction_get_page(dev, cache); 1481 if (spdk_unlikely(!page)) { 1482 return; 1483 } 1484 1485 if (page->updates) { 1486 page->state = L2P_CACHE_PAGE_FLUSHING; 1487 page->ctx.updates = page->updates; 1488 page_out_io(dev, cache, page); 1489 } else { 1490 /* Page clean and we can remove it */ 1491 ftl_l2p_cache_page_remove(cache, page); 1492 } 1493 } 1494 1495 static void 1496 ftl_l2p_lazy_unmap_process_cb(struct spdk_ftl_dev *dev, int status, struct ftl_l2p_pin_ctx *pin_ctx) 1497 { 1498 struct ftl_l2p_cache *cache = dev->l2p; 1499 1500 cache->lazy_unmap.qd--; 1501 1502 /* We will retry on next ftl_l2p_lazy_unmap_process */ 1503 if (spdk_unlikely(status != 0)) { 1504 return; 1505 } 1506 1507 if (ftl_l2p_cache_running(cache)) { 1508 ftl_l2p_cache_get(dev, pin_ctx->lba); 1509 } 1510 1511 ftl_l2p_cache_unpin(dev, pin_ctx->lba, pin_ctx->count); 1512 } 1513 1514 static void 1515 ftl_l2p_lazy_unmap_process(struct spdk_ftl_dev *dev) 1516 { 1517 struct ftl_l2p_cache *cache = dev->l2p; 1518 struct ftl_l2p_pin_ctx *pin_ctx; 1519 uint64_t page_no; 1520 1521 if (spdk_likely(!dev->unmap_in_progress)) { 1522 return; 1523 } 1524 1525 if (cache->lazy_unmap.qd == FTL_L2P_MAX_LAZY_UNMAP_QD) { 1526 return; 1527 } 1528 1529 page_no = ftl_bitmap_find_first_set(dev->unmap_map, cache->lazy_unmap.page_no, UINT64_MAX); 1530 if (page_no == UINT64_MAX) { 1531 cache->lazy_unmap.page_no = 0; 1532 1533 /* Check unmap map from beginning to detect unprocessed unmaps */ 1534 page_no = ftl_bitmap_find_first_set(dev->unmap_map, cache->lazy_unmap.page_no, UINT64_MAX); 1535 if (page_no == UINT64_MAX) { 1536 dev->unmap_in_progress = false; 1537 return; 1538 } 1539 } 1540 1541 cache->lazy_unmap.page_no = page_no; 1542 1543 pin_ctx = &cache->lazy_unmap.pin_ctx; 1544 1545 cache->lazy_unmap.qd++; 1546 assert(cache->lazy_unmap.qd <= FTL_L2P_MAX_LAZY_UNMAP_QD); 1547 assert(page_no < cache->num_pages); 1548 1549 pin_ctx->lba = page_no * cache->lbas_in_page; 1550 pin_ctx->count = 1; 1551 pin_ctx->cb = ftl_l2p_lazy_unmap_process_cb; 1552 pin_ctx->cb_ctx = pin_ctx; 1553 1554 ftl_l2p_cache_pin(dev, pin_ctx); 1555 } 1556 1557 void 1558 ftl_l2p_cache_process(struct spdk_ftl_dev *dev) 1559 { 1560 struct ftl_l2p_cache *cache = dev->l2p; 1561 int i; 1562 1563 if (spdk_unlikely(cache->state != L2P_CACHE_RUNNING)) { 1564 return; 1565 } 1566 1567 for (i = 0; i < 256; i++) { 1568 if (ftl_l2p_cache_process_page_sets(dev, cache)) { 1569 break; 1570 } 1571 } 1572 1573 ftl_l2p_cache_process_eviction(dev, cache); 1574 ftl_l2p_lazy_unmap_process(dev); 1575 } 1576