1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/crc32.h" 35 #include "spdk/likely.h" 36 #include "spdk/util.h" 37 #include "spdk/ftl.h" 38 39 #include "ftl_band.h" 40 #include "ftl_io.h" 41 #include "ftl_core.h" 42 #include "ftl_reloc.h" 43 #include "ftl_debug.h" 44 45 /* TODO: define some signature for meta version */ 46 #define FTL_MD_VER 1 47 48 struct __attribute__((packed)) ftl_md_hdr { 49 /* Device instance */ 50 struct spdk_uuid uuid; 51 52 /* Meta version */ 53 uint8_t ver; 54 55 /* Sequence number */ 56 uint64_t seq; 57 58 /* CRC32 checksum */ 59 uint32_t checksum; 60 }; 61 62 /* End metadata layout stored on media (with all three being aligned to block size): */ 63 /* - header */ 64 /* - valid bitmap */ 65 /* - LBA map */ 66 struct __attribute__((packed)) ftl_tail_md { 67 struct ftl_md_hdr hdr; 68 69 /* Max number of lbks */ 70 uint64_t num_lbks; 71 72 uint8_t reserved[4059]; 73 }; 74 SPDK_STATIC_ASSERT(sizeof(struct ftl_tail_md) == FTL_BLOCK_SIZE, "Incorrect metadata size"); 75 76 struct __attribute__((packed)) ftl_head_md { 77 struct ftl_md_hdr hdr; 78 79 /* Number of defrag cycles */ 80 uint64_t wr_cnt; 81 82 /* Number of surfaced LBAs */ 83 uint64_t lba_cnt; 84 85 /* Transfer size */ 86 uint32_t xfer_size; 87 }; 88 89 size_t 90 ftl_tail_md_hdr_num_lbks(void) 91 { 92 return spdk_divide_round_up(sizeof(struct ftl_tail_md), FTL_BLOCK_SIZE); 93 } 94 95 size_t 96 ftl_vld_map_num_lbks(const struct spdk_ftl_dev *dev) 97 { 98 return spdk_divide_round_up(ftl_vld_map_size(dev), FTL_BLOCK_SIZE); 99 } 100 101 size_t 102 ftl_lba_map_num_lbks(const struct spdk_ftl_dev *dev) 103 { 104 return spdk_divide_round_up(ftl_num_band_lbks(dev) * sizeof(uint64_t), FTL_BLOCK_SIZE); 105 } 106 107 size_t 108 ftl_head_md_num_lbks(const struct spdk_ftl_dev *dev) 109 { 110 return dev->xfer_size; 111 } 112 113 size_t 114 ftl_tail_md_num_lbks(const struct spdk_ftl_dev *dev) 115 { 116 return spdk_divide_round_up(ftl_tail_md_hdr_num_lbks() + 117 ftl_vld_map_num_lbks(dev) + 118 ftl_lba_map_num_lbks(dev), 119 dev->xfer_size) * dev->xfer_size; 120 } 121 122 static uint64_t 123 ftl_band_tail_md_offset(const struct ftl_band *band) 124 { 125 return ftl_band_num_usable_lbks(band) - 126 ftl_tail_md_num_lbks(band->dev); 127 } 128 129 int 130 ftl_band_full(struct ftl_band *band, size_t offset) 131 { 132 return offset == ftl_band_tail_md_offset(band); 133 } 134 135 void 136 ftl_band_write_failed(struct ftl_band *band) 137 { 138 struct spdk_ftl_dev *dev = band->dev; 139 140 band->high_prio = 1; 141 142 ftl_reloc_add(dev->reloc, band, 0, ftl_num_band_lbks(dev), 1, true); 143 ftl_band_set_state(band, FTL_BAND_STATE_CLOSED); 144 } 145 146 static void 147 ftl_band_free_lba_map(struct ftl_band *band) 148 { 149 struct spdk_ftl_dev *dev = band->dev; 150 struct ftl_lba_map *lba_map = &band->lba_map; 151 152 assert(band->state == FTL_BAND_STATE_CLOSED || 153 band->state == FTL_BAND_STATE_FREE); 154 assert(lba_map->ref_cnt == 0); 155 assert(lba_map->map != NULL); 156 assert(!band->high_prio); 157 158 /* Verify that band's metadata is consistent with l2p */ 159 if (band->num_chunks) { 160 assert(ftl_band_validate_md(band) == true); 161 } 162 163 spdk_mempool_put(dev->lba_pool, lba_map->dma_buf); 164 lba_map->map = NULL; 165 lba_map->dma_buf = NULL; 166 } 167 168 static void 169 _ftl_band_set_free(struct ftl_band *band) 170 { 171 struct spdk_ftl_dev *dev = band->dev; 172 struct ftl_band *lband, *prev; 173 174 /* Remove the band from the closed band list */ 175 LIST_REMOVE(band, list_entry); 176 177 /* Keep the list sorted by band's write count */ 178 LIST_FOREACH(lband, &dev->free_bands, list_entry) { 179 if (lband->wr_cnt > band->wr_cnt) { 180 LIST_INSERT_BEFORE(lband, band, list_entry); 181 break; 182 } 183 prev = lband; 184 } 185 186 if (!lband) { 187 if (LIST_EMPTY(&dev->free_bands)) { 188 LIST_INSERT_HEAD(&dev->free_bands, band, list_entry); 189 } else { 190 LIST_INSERT_AFTER(prev, band, list_entry); 191 } 192 } 193 194 #if defined(DEBUG) 195 prev = NULL; 196 LIST_FOREACH(lband, &dev->free_bands, list_entry) { 197 if (!prev) { 198 continue; 199 } 200 assert(prev->wr_cnt <= lband->wr_cnt); 201 } 202 #endif 203 dev->num_free++; 204 ftl_apply_limits(dev); 205 } 206 207 static void 208 _ftl_band_set_preparing(struct ftl_band *band) 209 { 210 struct spdk_ftl_dev *dev = band->dev; 211 212 /* Remove band from free list */ 213 LIST_REMOVE(band, list_entry); 214 215 band->wr_cnt++; 216 217 assert(dev->num_free > 0); 218 dev->num_free--; 219 220 ftl_apply_limits(dev); 221 } 222 223 static void 224 _ftl_band_set_closed(struct ftl_band *band) 225 { 226 struct spdk_ftl_dev *dev = band->dev; 227 struct ftl_chunk *chunk; 228 229 /* Set the state as free_md() checks for that */ 230 band->state = FTL_BAND_STATE_CLOSED; 231 232 /* Free the lba map if there are no outstanding IOs */ 233 ftl_band_release_lba_map(band); 234 235 if (spdk_likely(band->num_chunks)) { 236 LIST_INSERT_HEAD(&dev->shut_bands, band, list_entry); 237 CIRCLEQ_FOREACH(chunk, &band->chunks, circleq) { 238 chunk->state = FTL_CHUNK_STATE_CLOSED; 239 } 240 } else { 241 LIST_REMOVE(band, list_entry); 242 } 243 } 244 245 static uint32_t 246 ftl_md_calc_crc(const struct ftl_md_hdr *hdr, size_t size) 247 { 248 size_t checkoff = offsetof(struct ftl_md_hdr, checksum); 249 size_t mdoff = checkoff + sizeof(hdr->checksum); 250 uint32_t crc; 251 252 crc = spdk_crc32c_update(hdr, checkoff, 0); 253 return spdk_crc32c_update((const char *)hdr + mdoff, size - mdoff, crc); 254 } 255 256 static void 257 ftl_set_md_hdr(struct ftl_band *band, struct ftl_md_hdr *hdr, size_t size) 258 { 259 hdr->seq = band->seq; 260 hdr->ver = FTL_MD_VER; 261 hdr->uuid = band->dev->uuid; 262 hdr->checksum = ftl_md_calc_crc(hdr, size); 263 } 264 265 static int 266 ftl_pack_head_md(struct ftl_band *band) 267 { 268 struct spdk_ftl_dev *dev = band->dev; 269 struct ftl_head_md *head = band->lba_map.dma_buf; 270 271 head->wr_cnt = band->wr_cnt; 272 head->lba_cnt = dev->num_lbas; 273 head->xfer_size = dev->xfer_size; 274 ftl_set_md_hdr(band, &head->hdr, sizeof(struct ftl_head_md)); 275 276 return FTL_MD_SUCCESS; 277 } 278 279 static int 280 ftl_pack_tail_md(struct ftl_band *band) 281 { 282 struct spdk_ftl_dev *dev = band->dev; 283 struct ftl_lba_map *lba_map = &band->lba_map; 284 struct ftl_tail_md *tail = lba_map->dma_buf; 285 void *vld_offset; 286 287 vld_offset = (char *)tail + ftl_tail_md_hdr_num_lbks() * FTL_BLOCK_SIZE; 288 289 /* Clear out the buffer */ 290 memset(tail, 0, ftl_tail_md_hdr_num_lbks() * FTL_BLOCK_SIZE); 291 tail->num_lbks = ftl_num_band_lbks(dev); 292 293 pthread_spin_lock(&lba_map->lock); 294 spdk_bit_array_store_mask(lba_map->vld, vld_offset); 295 pthread_spin_unlock(&lba_map->lock); 296 297 ftl_set_md_hdr(band, &tail->hdr, ftl_tail_md_num_lbks(dev) * FTL_BLOCK_SIZE); 298 299 return FTL_MD_SUCCESS; 300 } 301 302 static int 303 ftl_md_hdr_vld(struct spdk_ftl_dev *dev, const struct ftl_md_hdr *hdr, size_t size) 304 { 305 if (spdk_uuid_compare(&dev->uuid, &hdr->uuid) != 0) { 306 return FTL_MD_NO_MD; 307 } 308 309 if (hdr->ver != FTL_MD_VER) { 310 return FTL_MD_INVALID_VER; 311 } 312 313 if (ftl_md_calc_crc(hdr, size) != hdr->checksum) { 314 return FTL_MD_INVALID_CRC; 315 } 316 317 return FTL_MD_SUCCESS; 318 } 319 320 static int 321 ftl_unpack_tail_md(struct ftl_band *band) 322 { 323 struct spdk_ftl_dev *dev = band->dev; 324 void *vld_offset; 325 struct ftl_lba_map *lba_map = &band->lba_map; 326 struct ftl_tail_md *tail = lba_map->dma_buf; 327 int rc; 328 329 vld_offset = (char *)tail + ftl_tail_md_hdr_num_lbks() * FTL_BLOCK_SIZE; 330 331 rc = ftl_md_hdr_vld(dev, &tail->hdr, ftl_tail_md_num_lbks(dev) * FTL_BLOCK_SIZE); 332 if (rc) { 333 return rc; 334 } 335 336 /* 337 * When restoring from a dirty shutdown it's possible old tail meta wasn't yet cleared - 338 * band had saved head meta, but didn't manage to send erase to all chunks. 339 * The already found tail md header is valid, but inconsistent with the head meta. Treat 340 * such a band as open/without valid tail md. 341 */ 342 if (band->seq != tail->hdr.seq) { 343 return FTL_MD_NO_MD; 344 } 345 346 if (tail->num_lbks != ftl_num_band_lbks(dev)) { 347 return FTL_MD_INVALID_SIZE; 348 } 349 350 spdk_bit_array_load_mask(lba_map->vld, vld_offset); 351 352 return FTL_MD_SUCCESS; 353 } 354 355 static int 356 ftl_unpack_head_md(struct ftl_band *band) 357 { 358 struct spdk_ftl_dev *dev = band->dev; 359 struct ftl_head_md *head = band->lba_map.dma_buf; 360 int rc; 361 362 rc = ftl_md_hdr_vld(dev, &head->hdr, sizeof(struct ftl_head_md)); 363 if (rc) { 364 return rc; 365 } 366 367 band->seq = head->hdr.seq; 368 band->wr_cnt = head->wr_cnt; 369 370 if (dev->global_md.num_lbas == 0) { 371 dev->global_md.num_lbas = head->lba_cnt; 372 } 373 374 if (dev->global_md.num_lbas != head->lba_cnt) { 375 return FTL_MD_INVALID_SIZE; 376 } 377 378 if (dev->xfer_size != head->xfer_size) { 379 return FTL_MD_INVALID_SIZE; 380 } 381 382 return FTL_MD_SUCCESS; 383 } 384 385 struct ftl_ppa 386 ftl_band_tail_md_ppa(struct ftl_band *band) 387 { 388 struct ftl_ppa ppa = {}; 389 struct ftl_chunk *chunk; 390 struct spdk_ftl_dev *dev = band->dev; 391 size_t xfer_size = dev->xfer_size; 392 size_t num_req = ftl_band_tail_md_offset(band) / xfer_size; 393 size_t i; 394 395 if (spdk_unlikely(!band->num_chunks)) { 396 return ftl_to_ppa(FTL_PPA_INVALID); 397 } 398 399 /* Metadata should be aligned to xfer size */ 400 assert(ftl_band_tail_md_offset(band) % xfer_size == 0); 401 402 chunk = CIRCLEQ_FIRST(&band->chunks); 403 for (i = 0; i < num_req % band->num_chunks; ++i) { 404 chunk = ftl_band_next_chunk(band, chunk); 405 } 406 407 ppa.lbk = (num_req / band->num_chunks) * xfer_size; 408 ppa.chk = band->id; 409 ppa.pu = chunk->punit->start_ppa.pu; 410 ppa.grp = chunk->punit->start_ppa.grp; 411 412 return ppa; 413 } 414 415 struct ftl_ppa 416 ftl_band_head_md_ppa(struct ftl_band *band) 417 { 418 struct ftl_ppa ppa; 419 420 if (spdk_unlikely(!band->num_chunks)) { 421 return ftl_to_ppa(FTL_PPA_INVALID); 422 } 423 424 ppa = CIRCLEQ_FIRST(&band->chunks)->punit->start_ppa; 425 ppa.chk = band->id; 426 427 return ppa; 428 } 429 430 void 431 ftl_band_set_state(struct ftl_band *band, enum ftl_band_state state) 432 { 433 switch (state) { 434 case FTL_BAND_STATE_FREE: 435 assert(band->state == FTL_BAND_STATE_CLOSED); 436 _ftl_band_set_free(band); 437 break; 438 439 case FTL_BAND_STATE_PREP: 440 assert(band->state == FTL_BAND_STATE_FREE); 441 _ftl_band_set_preparing(band); 442 break; 443 444 case FTL_BAND_STATE_CLOSED: 445 if (band->state != FTL_BAND_STATE_CLOSED) { 446 assert(band->state == FTL_BAND_STATE_CLOSING || band->high_prio); 447 _ftl_band_set_closed(band); 448 } 449 break; 450 451 default: 452 break; 453 } 454 455 band->state = state; 456 } 457 458 void 459 ftl_band_set_addr(struct ftl_band *band, uint64_t lba, struct ftl_ppa ppa) 460 { 461 struct ftl_lba_map *lba_map = &band->lba_map; 462 uint64_t offset; 463 464 assert(lba != FTL_LBA_INVALID); 465 466 offset = ftl_band_lbkoff_from_ppa(band, ppa); 467 pthread_spin_lock(&lba_map->lock); 468 469 lba_map->num_vld++; 470 lba_map->map[offset] = lba; 471 spdk_bit_array_set(lba_map->vld, offset); 472 473 pthread_spin_unlock(&lba_map->lock); 474 } 475 476 size_t 477 ftl_band_age(const struct ftl_band *band) 478 { 479 return (size_t)(band->dev->seq - band->seq); 480 } 481 482 size_t 483 ftl_band_num_usable_lbks(const struct ftl_band *band) 484 { 485 return band->num_chunks * ftl_dev_lbks_in_chunk(band->dev); 486 } 487 488 size_t 489 ftl_band_user_lbks_left(const struct ftl_band *band, size_t offset) 490 { 491 size_t tail_md_offset = ftl_band_tail_md_offset(band); 492 493 if (spdk_unlikely(offset <= ftl_head_md_num_lbks(band->dev))) { 494 return ftl_band_user_lbks(band); 495 } 496 497 if (spdk_unlikely(offset > tail_md_offset)) { 498 return 0; 499 } 500 501 return tail_md_offset - offset; 502 } 503 504 size_t 505 ftl_band_user_lbks(const struct ftl_band *band) 506 { 507 return ftl_band_num_usable_lbks(band) - 508 ftl_head_md_num_lbks(band->dev) - 509 ftl_tail_md_num_lbks(band->dev); 510 } 511 512 struct ftl_band * 513 ftl_band_from_ppa(struct spdk_ftl_dev *dev, struct ftl_ppa ppa) 514 { 515 assert(ppa.chk < ftl_dev_num_bands(dev)); 516 return &dev->bands[ppa.chk]; 517 } 518 519 struct ftl_chunk * 520 ftl_band_chunk_from_ppa(struct ftl_band *band, struct ftl_ppa ppa) 521 { 522 struct spdk_ftl_dev *dev = band->dev; 523 unsigned int punit; 524 525 punit = ftl_ppa_flatten_punit(dev, ppa); 526 assert(punit < ftl_dev_num_punits(dev)); 527 528 return &band->chunk_buf[punit]; 529 } 530 531 uint64_t 532 ftl_band_lbkoff_from_ppa(struct ftl_band *band, struct ftl_ppa ppa) 533 { 534 struct spdk_ftl_dev *dev = band->dev; 535 unsigned int punit; 536 537 punit = ftl_ppa_flatten_punit(dev, ppa); 538 assert(ppa.chk == band->id); 539 540 return punit * ftl_dev_lbks_in_chunk(dev) + ppa.lbk; 541 } 542 543 struct ftl_ppa 544 ftl_band_next_xfer_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t num_lbks) 545 { 546 struct spdk_ftl_dev *dev = band->dev; 547 struct ftl_chunk *chunk; 548 unsigned int punit_num; 549 size_t num_xfers, num_stripes; 550 551 assert(ppa.chk == band->id); 552 553 punit_num = ftl_ppa_flatten_punit(dev, ppa); 554 chunk = &band->chunk_buf[punit_num]; 555 556 num_lbks += (ppa.lbk % dev->xfer_size); 557 ppa.lbk -= (ppa.lbk % dev->xfer_size); 558 559 #if defined(DEBUG) 560 /* Check that the number of chunks has not been changed */ 561 struct ftl_chunk *_chunk; 562 size_t _num_chunks = 0; 563 CIRCLEQ_FOREACH(_chunk, &band->chunks, circleq) { 564 if (spdk_likely(_chunk->state != FTL_CHUNK_STATE_BAD)) { 565 _num_chunks++; 566 } 567 } 568 assert(band->num_chunks == _num_chunks); 569 #endif 570 assert(band->num_chunks != 0); 571 num_stripes = (num_lbks / dev->xfer_size) / band->num_chunks; 572 ppa.lbk += num_stripes * dev->xfer_size; 573 num_lbks -= num_stripes * dev->xfer_size * band->num_chunks; 574 575 if (ppa.lbk > ftl_dev_lbks_in_chunk(dev)) { 576 return ftl_to_ppa(FTL_PPA_INVALID); 577 } 578 579 num_xfers = num_lbks / dev->xfer_size; 580 for (size_t i = 0; i < num_xfers; ++i) { 581 /* When the last chunk is reached the lbk part of the address */ 582 /* needs to be increased by xfer_size */ 583 if (ftl_band_chunk_is_last(band, chunk)) { 584 ppa.lbk += dev->xfer_size; 585 if (ppa.lbk > ftl_dev_lbks_in_chunk(dev)) { 586 return ftl_to_ppa(FTL_PPA_INVALID); 587 } 588 } 589 590 chunk = ftl_band_next_operational_chunk(band, chunk); 591 assert(chunk); 592 ppa.grp = chunk->start_ppa.grp; 593 ppa.pu = chunk->start_ppa.pu; 594 595 num_lbks -= dev->xfer_size; 596 } 597 598 if (num_lbks) { 599 ppa.lbk += num_lbks; 600 if (ppa.lbk > ftl_dev_lbks_in_chunk(dev)) { 601 return ftl_to_ppa(FTL_PPA_INVALID); 602 } 603 } 604 605 return ppa; 606 } 607 608 static size_t 609 ftl_xfer_offset_from_ppa(struct ftl_band *band, struct ftl_ppa ppa) 610 { 611 struct ftl_chunk *chunk, *current_chunk; 612 unsigned int punit_offset = 0; 613 size_t off, num_stripes, xfer_size = band->dev->xfer_size; 614 615 assert(ppa.chk == band->id); 616 617 num_stripes = (ppa.lbk / xfer_size) * band->num_chunks; 618 off = ppa.lbk % xfer_size; 619 620 current_chunk = ftl_band_chunk_from_ppa(band, ppa); 621 CIRCLEQ_FOREACH(chunk, &band->chunks, circleq) { 622 if (current_chunk == chunk) { 623 break; 624 } 625 punit_offset++; 626 } 627 628 return xfer_size * (num_stripes + punit_offset) + off; 629 } 630 631 struct ftl_ppa 632 ftl_band_ppa_from_lbkoff(struct ftl_band *band, uint64_t lbkoff) 633 { 634 struct ftl_ppa ppa = { .ppa = 0 }; 635 struct spdk_ftl_dev *dev = band->dev; 636 uint64_t punit; 637 638 punit = lbkoff / ftl_dev_lbks_in_chunk(dev) + dev->range.begin; 639 640 ppa.lbk = lbkoff % ftl_dev_lbks_in_chunk(dev); 641 ppa.chk = band->id; 642 ppa.pu = punit / dev->geo.num_grp; 643 ppa.grp = punit % dev->geo.num_grp; 644 645 return ppa; 646 } 647 648 struct ftl_ppa 649 ftl_band_next_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t offset) 650 { 651 uint64_t lbkoff = ftl_band_lbkoff_from_ppa(band, ppa); 652 return ftl_band_ppa_from_lbkoff(band, lbkoff + offset); 653 } 654 655 void 656 ftl_band_acquire_lba_map(struct ftl_band *band) 657 { 658 assert(band->lba_map.map != NULL); 659 band->lba_map.ref_cnt++; 660 } 661 662 int 663 ftl_band_alloc_lba_map(struct ftl_band *band) 664 { 665 struct spdk_ftl_dev *dev = band->dev; 666 struct ftl_lba_map *lba_map = &band->lba_map; 667 668 assert(lba_map->ref_cnt == 0); 669 assert(lba_map->map == NULL); 670 671 lba_map->dma_buf = spdk_mempool_get(dev->lba_pool); 672 673 if (!lba_map->dma_buf) { 674 return -1; 675 } 676 677 memset(lba_map->dma_buf, 0, ftl_lba_map_pool_elem_size(band->dev)); 678 679 lba_map->map = (uint64_t *)((char *)lba_map->dma_buf + FTL_BLOCK_SIZE * 680 (ftl_tail_md_hdr_num_lbks() + ftl_vld_map_num_lbks(dev))); 681 682 lba_map->segments = (char *)lba_map->dma_buf + ftl_tail_md_num_lbks(dev) * FTL_BLOCK_SIZE; 683 684 ftl_band_acquire_lba_map(band); 685 return 0; 686 } 687 688 void 689 ftl_band_release_lba_map(struct ftl_band *band) 690 { 691 struct ftl_lba_map *lba_map = &band->lba_map; 692 693 assert(lba_map->map != NULL); 694 assert(lba_map->ref_cnt > 0); 695 lba_map->ref_cnt--; 696 697 if (lba_map->ref_cnt == 0) { 698 ftl_band_free_lba_map(band); 699 } 700 } 701 702 static void 703 ftl_read_md_cb(struct ftl_io *io, void *arg, int status) 704 { 705 struct ftl_md_io *md_io = (struct ftl_md_io *)io; 706 707 if (!status) { 708 status = md_io->pack_fn(md_io->io.band); 709 } else { 710 status = FTL_MD_IO_FAILURE; 711 } 712 713 md_io->cb_fn(io, md_io->cb_ctx, status); 714 } 715 716 static struct ftl_md_io * 717 ftl_io_init_md_read(struct spdk_ftl_dev *dev, struct ftl_ppa ppa, 718 struct ftl_band *band, size_t lbk_cnt, void *buf, 719 ftl_io_fn fn, ftl_md_pack_fn pack_fn, ftl_io_fn cb_fn, void *cb_ctx) 720 { 721 struct ftl_md_io *io; 722 struct ftl_io_init_opts opts = { 723 .dev = dev, 724 .io = NULL, 725 .rwb_batch = NULL, 726 .band = band, 727 .size = sizeof(*io), 728 .flags = FTL_IO_MD | FTL_IO_PPA_MODE, 729 .type = FTL_IO_READ, 730 .lbk_cnt = lbk_cnt, 731 .cb_fn = fn, 732 .data = buf, 733 }; 734 735 io = (struct ftl_md_io *)ftl_io_init_internal(&opts); 736 if (!io) { 737 return NULL; 738 } 739 740 io->io.ppa = ppa; 741 io->pack_fn = pack_fn; 742 io->cb_fn = cb_fn; 743 io->cb_ctx = cb_ctx; 744 745 return io; 746 } 747 748 static struct ftl_io * 749 ftl_io_init_md_write(struct spdk_ftl_dev *dev, struct ftl_band *band, 750 void *data, size_t lbk_cnt, ftl_io_fn cb) 751 { 752 struct ftl_io_init_opts opts = { 753 .dev = dev, 754 .io = NULL, 755 .rwb_batch = NULL, 756 .band = band, 757 .size = sizeof(struct ftl_io), 758 .flags = FTL_IO_MD | FTL_IO_PPA_MODE, 759 .type = FTL_IO_WRITE, 760 .lbk_cnt = lbk_cnt, 761 .cb_fn = cb, 762 .data = data, 763 .md = NULL, 764 }; 765 766 return ftl_io_init_internal(&opts); 767 } 768 769 static int 770 ftl_band_write_md(struct ftl_band *band, size_t lbk_cnt, 771 ftl_md_pack_fn md_fn, ftl_io_fn cb) 772 { 773 struct spdk_ftl_dev *dev = band->dev; 774 struct ftl_io *io; 775 776 io = ftl_io_init_md_write(dev, band, band->lba_map.dma_buf, lbk_cnt, cb); 777 if (!io) { 778 return -ENOMEM; 779 } 780 781 md_fn(band); 782 783 ftl_io_write(io); 784 return 0; 785 } 786 787 void 788 ftl_band_md_clear(struct ftl_band *band) 789 { 790 band->seq = 0; 791 band->wr_cnt = 0; 792 band->lba_map.num_vld = 0; 793 band->lba_map.map = NULL; 794 } 795 796 int 797 ftl_band_write_head_md(struct ftl_band *band, ftl_io_fn cb) 798 { 799 return ftl_band_write_md(band, ftl_head_md_num_lbks(band->dev), 800 ftl_pack_head_md, cb); 801 } 802 803 int 804 ftl_band_write_tail_md(struct ftl_band *band, ftl_io_fn cb) 805 { 806 return ftl_band_write_md(band, ftl_tail_md_num_lbks(band->dev), 807 ftl_pack_tail_md, cb); 808 } 809 810 static struct ftl_ppa 811 ftl_band_lba_map_ppa(struct ftl_band *band, size_t offset) 812 { 813 return ftl_band_next_xfer_ppa(band, band->tail_md_ppa, 814 ftl_tail_md_hdr_num_lbks() + 815 ftl_vld_map_num_lbks(band->dev) + 816 offset); 817 } 818 819 static int 820 ftl_band_read_md(struct ftl_band *band, size_t lbk_cnt, struct ftl_ppa start_ppa, 821 void *buf, ftl_io_fn fn, ftl_md_pack_fn pack_fn, ftl_io_fn cb_fn, void *cb_ctx) 822 { 823 struct spdk_ftl_dev *dev = band->dev; 824 struct ftl_md_io *io; 825 826 if (spdk_unlikely(!band->num_chunks)) { 827 return -ENOENT; 828 } 829 830 io = ftl_io_init_md_read(dev, start_ppa, band, lbk_cnt, buf, fn, pack_fn, cb_fn, cb_ctx); 831 if (!io) { 832 return -ENOMEM; 833 } 834 835 ftl_io_read((struct ftl_io *)io); 836 return 0; 837 } 838 839 int 840 ftl_band_read_tail_md(struct ftl_band *band, struct ftl_ppa ppa, ftl_io_fn cb_fn, void *cb_ctx) 841 { 842 return ftl_band_read_md(band, ftl_tail_md_num_lbks(band->dev), ppa, band->lba_map.dma_buf, 843 ftl_read_md_cb, ftl_unpack_tail_md, cb_fn, cb_ctx); 844 } 845 846 static size_t 847 ftl_lba_map_request_segment_done(struct ftl_lba_map_request *request, size_t offset, 848 size_t num_segments) 849 { 850 size_t i, num_done = 0; 851 852 for (i = offset; i < offset + num_segments; ++i) { 853 if (spdk_bit_array_get(request->segments, i)) { 854 spdk_bit_array_clear(request->segments, offset); 855 num_done++; 856 } 857 } 858 859 assert(request->num_pending >= num_done); 860 request->num_pending -= num_done; 861 862 return num_done; 863 } 864 865 static void 866 ftl_lba_map_set_segment_state(struct ftl_lba_map *lba_map, size_t offset, size_t num_segments, 867 enum ftl_lba_map_seg_state state) 868 { 869 size_t i; 870 871 for (i = offset; i < offset + num_segments; ++i) { 872 lba_map->segments[i] = state; 873 } 874 } 875 876 static void 877 ftl_lba_map_request_free(struct spdk_ftl_dev *dev, struct ftl_lba_map_request *request) 878 { 879 spdk_bit_array_clear_mask(request->segments); 880 spdk_mempool_put(dev->lba_request_pool, request); 881 } 882 883 static void 884 ftl_process_lba_map_requests(struct spdk_ftl_dev *dev, struct ftl_lba_map *lba_map, size_t offset, 885 size_t num_segments, int status) 886 { 887 struct ftl_lba_map_request *request, *trequest; 888 size_t num_done; 889 890 LIST_FOREACH_SAFE(request, &lba_map->request_list, list_entry, trequest) { 891 num_done = ftl_lba_map_request_segment_done(request, offset, num_segments); 892 if (request->num_pending == 0 || (status && num_done)) { 893 request->cb(NULL, request->cb_ctx, status); 894 LIST_REMOVE(request, list_entry); 895 ftl_lba_map_request_free(dev, request); 896 } 897 } 898 } 899 900 static size_t 901 ftl_lba_map_offset_from_ppa(struct ftl_band *band, struct ftl_ppa ppa) 902 { 903 size_t offset; 904 struct ftl_ppa start_ppa = ftl_band_lba_map_ppa(band, 0); 905 906 offset = ftl_xfer_offset_from_ppa(band, ppa) - ftl_xfer_offset_from_ppa(band, start_ppa); 907 assert(offset < ftl_lba_map_num_lbks(band->dev)); 908 909 return offset; 910 } 911 912 static void 913 ftl_read_lba_map_cb(struct ftl_io *io, void *arg, int status) 914 { 915 struct ftl_lba_map *lba_map = &io->band->lba_map; 916 uint64_t lbk_off; 917 918 lbk_off = ftl_lba_map_offset_from_ppa(io->band, io->ppa); 919 assert(lbk_off + io->lbk_cnt <= ftl_lba_map_num_lbks(io->dev)); 920 921 if (!status) { 922 ftl_lba_map_set_segment_state(lba_map, lbk_off, io->lbk_cnt, 923 FTL_LBA_MAP_SEG_CACHED); 924 } 925 926 ftl_process_lba_map_requests(io->dev, lba_map, lbk_off, io->lbk_cnt, status); 927 } 928 929 static struct ftl_lba_map_request * 930 ftl_lba_map_alloc_request(struct ftl_band *band, size_t offset, size_t num_segments, 931 ftl_io_fn cb, void *cb_ctx) 932 { 933 struct ftl_lba_map_request *request; 934 struct spdk_ftl_dev *dev = band->dev; 935 size_t i; 936 937 request = spdk_mempool_get(dev->lba_request_pool); 938 if (!request) { 939 return NULL; 940 } 941 942 request->cb = cb; 943 request->cb_ctx = cb_ctx; 944 request->num_pending = num_segments; 945 946 for (i = offset; i < offset + num_segments; ++i) { 947 spdk_bit_array_set(request->segments, i); 948 } 949 950 return request; 951 } 952 953 static size_t 954 ftl_lba_map_num_clear_segments(struct ftl_lba_map *lba_map, 955 size_t offset, size_t num_segments) 956 { 957 size_t i, cnt = 0; 958 959 for (i = offset; i < offset + num_segments; ++i) { 960 if (lba_map->segments[i] != FTL_LBA_MAP_SEG_CLEAR) { 961 break; 962 } 963 cnt++; 964 } 965 966 return cnt; 967 } 968 969 int 970 ftl_band_read_lba_map(struct ftl_band *band, size_t offset, size_t lba_cnt, 971 ftl_io_fn cb_fn, void *cb_ctx) 972 { 973 size_t lbk_cnt, lbk_off, num_read, num_segments; 974 struct ftl_lba_map *lba_map = &band->lba_map; 975 struct ftl_lba_map_request *request; 976 int rc = 0; 977 978 lbk_off = offset / FTL_NUM_LBA_IN_BLOCK; 979 num_segments = spdk_divide_round_up(offset + lba_cnt, FTL_NUM_LBA_IN_BLOCK); 980 lbk_cnt = num_segments - lbk_off; 981 assert(lbk_off + lbk_cnt <= ftl_lba_map_num_lbks(band->dev)); 982 983 request = ftl_lba_map_alloc_request(band, lbk_off, lbk_cnt, cb_fn, cb_ctx); 984 if (!request) { 985 return -ENOMEM; 986 } 987 988 while (lbk_cnt) { 989 if (lba_map->segments[lbk_off] != FTL_LBA_MAP_SEG_CLEAR) { 990 if (lba_map->segments[lbk_off] == FTL_LBA_MAP_SEG_CACHED) { 991 ftl_lba_map_request_segment_done(request, lbk_off, 1); 992 } 993 lbk_cnt--; 994 lbk_off++; 995 continue; 996 } 997 998 num_read = ftl_lba_map_num_clear_segments(lba_map, lbk_off, lbk_cnt); 999 ftl_lba_map_set_segment_state(lba_map, lbk_off, num_read, 1000 FTL_LBA_MAP_SEG_PENDING); 1001 1002 rc = ftl_band_read_md(band, num_read, ftl_band_lba_map_ppa(band, lbk_off), 1003 (char *)band->lba_map.map + lbk_off * FTL_BLOCK_SIZE, 1004 ftl_read_lba_map_cb, NULL, cb_fn, cb_ctx); 1005 if (rc) { 1006 ftl_lba_map_request_free(band->dev, request); 1007 return rc; 1008 } 1009 1010 assert(lbk_cnt >= num_read); 1011 lbk_cnt -= num_read; 1012 lbk_off += num_read; 1013 } 1014 1015 if (request->num_pending) { 1016 LIST_INSERT_HEAD(&lba_map->request_list, request, list_entry); 1017 } else { 1018 cb_fn(NULL, cb_ctx, 0); 1019 ftl_lba_map_request_free(band->dev, request); 1020 } 1021 1022 return rc; 1023 } 1024 1025 int 1026 ftl_band_read_head_md(struct ftl_band *band, ftl_io_fn cb_fn, void *cb_ctx) 1027 { 1028 return ftl_band_read_md(band, 1029 ftl_head_md_num_lbks(band->dev), 1030 ftl_band_head_md_ppa(band), 1031 band->lba_map.dma_buf, 1032 ftl_read_md_cb, 1033 ftl_unpack_head_md, 1034 cb_fn, 1035 cb_ctx); 1036 } 1037 1038 static void 1039 ftl_band_remove_chunk(struct ftl_band *band, struct ftl_chunk *chunk) 1040 { 1041 CIRCLEQ_REMOVE(&band->chunks, chunk, circleq); 1042 band->num_chunks--; 1043 } 1044 1045 static void 1046 ftl_erase_fail(struct ftl_io *io, int status) 1047 { 1048 struct ftl_chunk *chunk; 1049 struct ftl_band *band = io->band; 1050 char buf[128]; 1051 1052 SPDK_ERRLOG("Erase failed @ppa: %s, status: %d\n", 1053 ftl_ppa2str(io->ppa, buf, sizeof(buf)), status); 1054 1055 chunk = ftl_band_chunk_from_ppa(band, io->ppa); 1056 chunk->state = FTL_CHUNK_STATE_BAD; 1057 ftl_band_remove_chunk(band, chunk); 1058 band->tail_md_ppa = ftl_band_tail_md_ppa(band); 1059 } 1060 1061 static void 1062 ftl_band_erase_cb(struct ftl_io *io, void *ctx, int status) 1063 { 1064 struct ftl_chunk *chunk; 1065 1066 if (spdk_unlikely(status)) { 1067 ftl_erase_fail(io, status); 1068 return; 1069 } 1070 chunk = ftl_band_chunk_from_ppa(io->band, io->ppa); 1071 chunk->state = FTL_CHUNK_STATE_FREE; 1072 chunk->write_offset = 0; 1073 } 1074 1075 int 1076 ftl_band_erase(struct ftl_band *band) 1077 { 1078 struct ftl_chunk *chunk; 1079 struct ftl_io *io; 1080 int rc = 0; 1081 1082 assert(band->state == FTL_BAND_STATE_CLOSED || 1083 band->state == FTL_BAND_STATE_FREE); 1084 1085 ftl_band_set_state(band, FTL_BAND_STATE_PREP); 1086 1087 CIRCLEQ_FOREACH(chunk, &band->chunks, circleq) { 1088 if (chunk->state == FTL_CHUNK_STATE_FREE) { 1089 continue; 1090 } 1091 1092 io = ftl_io_erase_init(band, 1, ftl_band_erase_cb); 1093 if (!io) { 1094 rc = -ENOMEM; 1095 break; 1096 } 1097 1098 io->ppa = chunk->start_ppa; 1099 rc = ftl_io_erase(io); 1100 if (rc) { 1101 assert(0); 1102 /* TODO: change band's state back to close? */ 1103 break; 1104 } 1105 } 1106 1107 return rc; 1108 } 1109 1110 int 1111 ftl_band_write_prep(struct ftl_band *band) 1112 { 1113 struct spdk_ftl_dev *dev = band->dev; 1114 1115 if (ftl_band_alloc_lba_map(band)) { 1116 return -1; 1117 } 1118 1119 band->seq = ++dev->seq; 1120 return 0; 1121 } 1122 1123 struct ftl_chunk * 1124 ftl_band_next_operational_chunk(struct ftl_band *band, struct ftl_chunk *chunk) 1125 { 1126 struct ftl_chunk *result = NULL; 1127 struct ftl_chunk *entry; 1128 1129 if (spdk_unlikely(!band->num_chunks)) { 1130 return NULL; 1131 } 1132 1133 /* Erasing band may fail after it was assigned to wptr. */ 1134 /* In such a case chunk is no longer in band->chunks queue. */ 1135 if (spdk_likely(chunk->state != FTL_CHUNK_STATE_BAD)) { 1136 result = ftl_band_next_chunk(band, chunk); 1137 } else { 1138 CIRCLEQ_FOREACH_REVERSE(entry, &band->chunks, circleq) { 1139 if (entry->pos > chunk->pos) { 1140 result = entry; 1141 } else { 1142 if (!result) { 1143 result = CIRCLEQ_FIRST(&band->chunks); 1144 } 1145 break; 1146 } 1147 } 1148 } 1149 1150 return result; 1151 } 1152 1153 void 1154 ftl_band_clear_lba_map(struct ftl_band *band) 1155 { 1156 struct ftl_lba_map *lba_map = &band->lba_map; 1157 size_t num_segments; 1158 1159 spdk_bit_array_clear_mask(lba_map->vld); 1160 memset(lba_map->map, 0, ftl_lba_map_num_lbks(band->dev) * FTL_BLOCK_SIZE); 1161 1162 /* For open band all lba map segments are already cached */ 1163 assert(band->state == FTL_BAND_STATE_PREP); 1164 num_segments = spdk_divide_round_up(ftl_num_band_lbks(band->dev), FTL_NUM_LBA_IN_BLOCK); 1165 ftl_lba_map_set_segment_state(&band->lba_map, 0, num_segments, FTL_LBA_MAP_SEG_CACHED); 1166 1167 lba_map->num_vld = 0; 1168 } 1169 1170 size_t 1171 ftl_lba_map_pool_elem_size(struct spdk_ftl_dev *dev) 1172 { 1173 /* Map pool element holds the whole tail md + segments map */ 1174 return ftl_tail_md_num_lbks(dev) * FTL_BLOCK_SIZE + 1175 spdk_divide_round_up(ftl_num_band_lbks(dev), FTL_NUM_LBA_IN_BLOCK); 1176 } 1177