From 57cfab6808d604e9813378852f0c7145a9ddd25a Mon Sep 17 00:00:00 2001 From: Artur Paszkiewicz Date: Thu, 2 Jun 2022 09:53:50 +0200 Subject: [PATCH] ftl: use valid map to optimize compaction and reloc Utilize the valid map when picking physical blocks to compact/relocate, speeding up the process. Signed-off-by: Artur Paszkiewicz Signed-off-by: Kozlowski Mateusz Change-Id: I860e3cf25a5907591e4f3043def67156fec8b0df Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13351 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- lib/ftl/ftl_nv_cache.c | 30 ++++++++++++++++++++++++++++-- lib/ftl/ftl_reloc.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/lib/ftl/ftl_nv_cache.c b/lib/ftl/ftl_nv_cache.c index 1cb04f8d7..7b616755b 100644 --- a/lib/ftl/ftl_nv_cache.c +++ b/lib/ftl/ftl_nv_cache.c @@ -709,7 +709,7 @@ compaction_process(struct ftl_nv_cache_compactor *compactor) struct spdk_ftl_dev *dev = SPDK_CONTAINEROF(nv_cache, struct spdk_ftl_dev, nv_cache); struct ftl_nv_cache_chunk *chunk; - uint64_t to_read, addr; + uint64_t to_read, addr, begin, end, offset; int rc; /* Check if all read blocks done */ @@ -733,8 +733,34 @@ compaction_process(struct ftl_nv_cache_compactor *compactor) /* * Get range of blocks to read */ + to_read = chunk_blocks_to_read(chunk); + assert(to_read > 0); + addr = ftl_addr_from_nvc_offset(dev, chunk->offset + chunk->md->read_pointer); - to_read = spdk_min(chunk_blocks_to_read(chunk), compactor->rd->num_blocks); + begin = ftl_bitmap_find_first_set(dev->valid_map, addr, addr + to_read); + if (begin != UINT64_MAX) { + offset = spdk_min(begin - addr, to_read); + } else { + offset = to_read; + } + + if (offset) { + chunk->md->read_pointer += offset; + chunk_compaction_advance(chunk, offset); + to_read -= offset; + if (!to_read) { + compactor_deactivate(compactor); + return; + } + } + + end = ftl_bitmap_find_first_clear(dev->valid_map, begin + 1, begin + to_read); + if (end != UINT64_MAX) { + to_read = end - begin; + } + + addr = begin; + to_read = spdk_min(to_read, compactor->rd->num_blocks); /* Read data and metadata from NV cache */ rc = compaction_submit_read(compactor, addr, to_read); diff --git a/lib/ftl/ftl_reloc.c b/lib/ftl/ftl_reloc.c index 04455f3cf..a2381639a 100644 --- a/lib/ftl/ftl_reloc.c +++ b/lib/ftl/ftl_reloc.c @@ -372,11 +372,49 @@ static void move_read(struct ftl_reloc *reloc, struct ftl_reloc_move *mv, struct ftl_band *band) { struct ftl_rq *rq = mv->rq; - uint64_t band_left, rq_left; + uint64_t blocks = ftl_get_num_blocks_in_band(band->dev); + uint64_t pos = band->md->iter.offset; + uint64_t begin = ftl_bitmap_find_first_set(band->p2l_map.valid, pos, UINT64_MAX); + uint64_t end, band_left, rq_left; + + if (spdk_likely(begin < blocks)) { + if (begin > pos) { + ftl_band_iter_advance(band, begin - pos); + } else if (begin == pos) { + /* Valid block at the position of iterator */ + } else { + /* Inconsistent state */ + ftl_abort(); + } + } else if (UINT64_MAX == begin) { + /* No more valid LBAs in the band */ + band_left = ftl_band_user_blocks_left(band, pos); + ftl_band_iter_advance(band, band_left); + + assert(ftl_band_filled(band, band->md->iter.offset)); + + if (rq->iter.idx) { + move_rq_pad(rq, band); + move_set_state(mv, FTL_RELOC_STATE_WAIT); + rq->iter.qd++; + rq->owner.cb(rq); + } + + return; + } else { + /* Inconsistent state */ + ftl_abort(); + } rq_left = rq->num_blocks - rq->iter.idx; assert(rq_left > 0); + /* Find next clear bit, but no further than max request count */ + end = ftl_bitmap_find_first_clear(band->p2l_map.valid, begin + 1, begin + rq_left); + if (end != UINT64_MAX) { + rq_left = end - begin; + } + band_left = ftl_band_user_blocks_left(band, band->md->iter.offset); rq->iter.count = spdk_min(rq_left, band_left);