lib/ftl: track defragged bands in ftl_reloc
Track the band under defrag inside the reloc module. This allows for multiple bands being defragged at the same time (e.g. extra one due to write fault) as well as makes it easier to handle cases when relocating a band that has no valid blocks. Change-Id: Ia54916571040f5f4dfdb8f7cdb47f28435a466d8 Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/465937 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Mateusz Kozlowski <mateusz.kozlowski@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
407e88fd2a
commit
1f133d7279
@ -139,11 +139,7 @@ ftl_band_write_failed(struct ftl_band *band)
|
||||
|
||||
band->high_prio = 1;
|
||||
|
||||
if (!dev->df_band) {
|
||||
dev->df_band = band;
|
||||
}
|
||||
|
||||
ftl_reloc_add(dev->reloc, band, 0, ftl_num_band_lbks(dev), 1);
|
||||
ftl_reloc_add(dev->reloc, band, 0, ftl_num_band_lbks(dev), 1, true);
|
||||
ftl_band_set_state(band, FTL_BAND_STATE_CLOSED);
|
||||
}
|
||||
|
||||
@ -175,10 +171,6 @@ _ftl_band_set_free(struct ftl_band *band)
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
struct ftl_band *lband, *prev;
|
||||
|
||||
if (band == dev->df_band) {
|
||||
dev->df_band = NULL;
|
||||
}
|
||||
|
||||
/* Remove the band from the closed band list */
|
||||
LIST_REMOVE(band, list_entry);
|
||||
|
||||
|
@ -1792,7 +1792,7 @@ ftl_dev_needs_defrag(struct spdk_ftl_dev *dev)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dev->df_band) {
|
||||
if (ftl_reloc_is_defrag_active(dev->reloc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1867,10 +1867,9 @@ ftl_process_relocs(struct spdk_ftl_dev *dev)
|
||||
struct ftl_band *band;
|
||||
|
||||
if (ftl_dev_needs_defrag(dev)) {
|
||||
band = dev->df_band = ftl_select_defrag_band(dev);
|
||||
|
||||
band = ftl_select_defrag_band(dev);
|
||||
if (band) {
|
||||
ftl_reloc_add(dev->reloc, band, 0, ftl_num_band_lbks(dev), 0);
|
||||
ftl_reloc_add(dev->reloc, band, 0, ftl_num_band_lbks(dev), 0, true);
|
||||
ftl_trace_defrag_band(dev, band);
|
||||
}
|
||||
}
|
||||
@ -2135,7 +2134,7 @@ ftl_process_anm_event(struct ftl_anm_event *event)
|
||||
band = ftl_band_from_ppa(dev, event->ppa);
|
||||
lbkoff = ftl_band_lbkoff_from_ppa(band, event->ppa);
|
||||
|
||||
ftl_reloc_add(dev->reloc, band, lbkoff, event->num_lbks, 0);
|
||||
ftl_reloc_add(dev->reloc, band, lbkoff, event->num_lbks, 0, false);
|
||||
ftl_anm_event_complete(event);
|
||||
}
|
||||
|
||||
|
@ -191,8 +191,6 @@ struct spdk_ftl_dev {
|
||||
|
||||
/* Array of bands */
|
||||
struct ftl_band *bands;
|
||||
/* Band being curently defraged */
|
||||
struct ftl_band *df_band;
|
||||
/* Number of operational bands */
|
||||
size_t num_bands;
|
||||
/* Next write band */
|
||||
|
@ -87,6 +87,8 @@ struct ftl_band_reloc {
|
||||
|
||||
/* Indicates band being acitvely processed */
|
||||
int active;
|
||||
/* The band is being defragged */
|
||||
bool defrag;
|
||||
|
||||
/* Reloc map iterator */
|
||||
struct {
|
||||
@ -124,6 +126,8 @@ struct ftl_reloc {
|
||||
|
||||
/* Maximum transfer size (in logical blocks) per single IO */
|
||||
size_t xfer_size;
|
||||
/* Number of bands being defragged */
|
||||
size_t num_defrag_bands;
|
||||
|
||||
/* Array of band relocates */
|
||||
struct ftl_band_reloc *brelocs;
|
||||
@ -141,6 +145,12 @@ struct ftl_reloc {
|
||||
TAILQ_HEAD(, ftl_band_reloc) pending_queue;
|
||||
};
|
||||
|
||||
bool
|
||||
ftl_reloc_is_defrag_active(const struct ftl_reloc *reloc)
|
||||
{
|
||||
return reloc->num_defrag_bands > 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
ftl_reloc_iter_chk_offset(struct ftl_band_reloc *breloc)
|
||||
{
|
||||
@ -169,7 +179,6 @@ ftl_reloc_clr_lbk(struct ftl_band_reloc *breloc, size_t lbkoff)
|
||||
breloc->num_lbks--;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ftl_reloc_read_lba_map_cb(struct ftl_io *io, void *arg, int status)
|
||||
{
|
||||
@ -563,6 +572,12 @@ ftl_reloc_release(struct ftl_band_reloc *breloc)
|
||||
|
||||
if (ftl_band_empty(band) && band->state == FTL_BAND_STATE_CLOSED) {
|
||||
ftl_band_set_state(breloc->band, FTL_BAND_STATE_FREE);
|
||||
|
||||
if (breloc->defrag) {
|
||||
breloc->defrag = false;
|
||||
assert(reloc->num_defrag_bands > 0);
|
||||
reloc->num_defrag_bands--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -670,6 +685,7 @@ ftl_reloc_init(struct spdk_ftl_dev *dev)
|
||||
reloc->max_qdepth = dev->conf.max_reloc_qdepth;
|
||||
reloc->max_active = dev->conf.max_active_relocs;
|
||||
reloc->xfer_size = dev->xfer_size;
|
||||
reloc->num_defrag_bands = 0;
|
||||
|
||||
if (reloc->max_qdepth > FTL_RELOC_MAX_MOVES) {
|
||||
goto error;
|
||||
@ -775,7 +791,7 @@ ftl_reloc(struct ftl_reloc *reloc)
|
||||
|
||||
void
|
||||
ftl_reloc_add(struct ftl_reloc *reloc, struct ftl_band *band, size_t offset,
|
||||
size_t num_lbks, int prio)
|
||||
size_t num_lbks, int prio, bool is_defrag)
|
||||
{
|
||||
struct ftl_band_reloc *breloc = &reloc->brelocs[band->id];
|
||||
size_t i, prev_lbks = breloc->num_lbks;
|
||||
@ -788,6 +804,12 @@ ftl_reloc_add(struct ftl_reloc *reloc, struct ftl_band *band, size_t offset,
|
||||
pthread_spin_lock(&band->lba_map.lock);
|
||||
if (band->lba_map.num_vld == 0) {
|
||||
pthread_spin_unlock(&band->lba_map.lock);
|
||||
|
||||
/* If the band is closed and has no valid blocks, free it */
|
||||
if (band->state == FTL_BAND_STATE_CLOSED) {
|
||||
ftl_band_set_state(band, FTL_BAND_STATE_FREE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
pthread_spin_unlock(&band->lba_map.lock);
|
||||
@ -804,6 +826,13 @@ ftl_reloc_add(struct ftl_reloc *reloc, struct ftl_band *band, size_t offset,
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the band is coming from the defrag process, mark it appropriately */
|
||||
if (is_defrag) {
|
||||
assert(offset == 0 && num_lbks == ftl_num_band_lbks(band->dev));
|
||||
reloc->num_defrag_bands++;
|
||||
breloc->defrag = true;
|
||||
}
|
||||
|
||||
if (!prev_lbks && !prio && !breloc->active) {
|
||||
TAILQ_INSERT_HEAD(&reloc->pending_queue, breloc, entry);
|
||||
}
|
||||
|
@ -43,9 +43,11 @@ struct ftl_band;
|
||||
struct ftl_reloc *ftl_reloc_init(struct spdk_ftl_dev *dev);
|
||||
void ftl_reloc_free(struct ftl_reloc *reloc);
|
||||
void ftl_reloc_add(struct ftl_reloc *reloc, struct ftl_band *band,
|
||||
size_t offset, size_t num_lbks, int prio);
|
||||
size_t offset, size_t num_lbks, int prio, bool is_defrag);
|
||||
void ftl_reloc(struct ftl_reloc *reloc);
|
||||
void ftl_reloc_halt(struct ftl_reloc *reloc);
|
||||
void ftl_reloc_resume(struct ftl_reloc *reloc);
|
||||
bool ftl_reloc_is_halted(const struct ftl_reloc *reloc);
|
||||
bool ftl_reloc_is_defrag_active(const struct ftl_reloc *reloc);
|
||||
|
||||
#endif /* FTL_RELOC_H */
|
||||
|
@ -270,7 +270,7 @@ test_reloc_iter_full(void)
|
||||
|
||||
set_band_valid_map(band, 0, ftl_num_band_lbks(dev));
|
||||
|
||||
ftl_reloc_add(reloc, band, 0, ftl_num_band_lbks(dev), 0);
|
||||
ftl_reloc_add(reloc, band, 0, ftl_num_band_lbks(dev), 0, true);
|
||||
|
||||
CU_ASSERT_EQUAL(breloc->num_lbks, ftl_num_band_lbks(dev));
|
||||
|
||||
@ -313,7 +313,7 @@ test_reloc_empty_band(void)
|
||||
breloc = &reloc->brelocs[0];
|
||||
band = breloc->band;
|
||||
|
||||
ftl_reloc_add(reloc, band, 0, ftl_num_band_lbks(dev), 0);
|
||||
ftl_reloc_add(reloc, band, 0, ftl_num_band_lbks(dev), 0, true);
|
||||
|
||||
CU_ASSERT_EQUAL(breloc->num_lbks, 0);
|
||||
|
||||
@ -338,7 +338,7 @@ test_reloc_full_band(void)
|
||||
|
||||
set_band_valid_map(band, 0, ftl_num_band_lbks(dev));
|
||||
|
||||
ftl_reloc_add(reloc, band, 0, ftl_num_band_lbks(dev), 0);
|
||||
ftl_reloc_add(reloc, band, 0, ftl_num_band_lbks(dev), 0, true);
|
||||
|
||||
CU_ASSERT_EQUAL(breloc->num_lbks, ftl_num_band_lbks(dev));
|
||||
|
||||
@ -384,7 +384,7 @@ test_reloc_scatter_band(void)
|
||||
}
|
||||
}
|
||||
|
||||
ftl_reloc_add(reloc, band, 0, ftl_num_band_lbks(dev), 0);
|
||||
ftl_reloc_add(reloc, band, 0, ftl_num_band_lbks(dev), 0, true);
|
||||
ftl_reloc_add_active_queue(breloc);
|
||||
|
||||
CU_ASSERT_EQUAL(breloc->num_lbks, ftl_num_band_lbks(dev));
|
||||
@ -422,7 +422,7 @@ test_reloc_chunk(void)
|
||||
set_band_valid_map(band, 0, ftl_num_band_lbks(dev));
|
||||
|
||||
ftl_reloc_add(reloc, band, ftl_dev_lbks_in_chunk(dev) * 3,
|
||||
ftl_dev_lbks_in_chunk(dev), 1);
|
||||
ftl_dev_lbks_in_chunk(dev), 1, false);
|
||||
ftl_reloc_add_active_queue(breloc);
|
||||
|
||||
CU_ASSERT_EQUAL(breloc->num_lbks, ftl_dev_lbks_in_chunk(dev));
|
||||
@ -462,7 +462,7 @@ test_reloc_single_lbk(void)
|
||||
|
||||
set_band_valid_map(band, TEST_RELOC_OFFSET, 1);
|
||||
|
||||
ftl_reloc_add(reloc, band, TEST_RELOC_OFFSET, 1, 0);
|
||||
ftl_reloc_add(reloc, band, TEST_RELOC_OFFSET, 1, 0, false);
|
||||
SPDK_CU_ASSERT_FATAL(breloc == TAILQ_FIRST(&reloc->pending_queue));
|
||||
ftl_reloc_add_active_queue(breloc);
|
||||
|
||||
|
@ -63,7 +63,7 @@ DEFINE_STUB_V(ftl_io_fail, (struct ftl_io *io, int status));
|
||||
DEFINE_STUB_V(ftl_trace_completion, (struct spdk_ftl_dev *dev, const struct ftl_io *io,
|
||||
enum ftl_trace_completion completion));
|
||||
DEFINE_STUB_V(ftl_reloc_add, (struct ftl_reloc *reloc, struct ftl_band *band, size_t offset,
|
||||
size_t num_lbks, int prio));
|
||||
size_t num_lbks, int prio, bool defrag));
|
||||
DEFINE_STUB_V(ftl_trace_write_band, (struct spdk_ftl_dev *dev, const struct ftl_band *band));
|
||||
DEFINE_STUB_V(ftl_trace_submission, (struct spdk_ftl_dev *dev, const struct ftl_io *io,
|
||||
struct ftl_ppa ppa, size_t ppa_cnt));
|
||||
|
Loading…
Reference in New Issue
Block a user