Commit 1f133d72 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Jim Harris
Browse files

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: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/465937


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarMateusz Kozlowski <mateusz.kozlowski@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 407e88fd
Loading
Loading
Loading
Loading
+1 −9
Original line number Diff line number Diff line
@@ -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);

+4 −5
Original line number Diff line number Diff line
@@ -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);
}

+0 −2
Original line number Diff line number Diff line
@@ -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 */
+31 −2
Original line number Diff line number Diff line
@@ -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);
	}
+3 −1
Original line number Diff line number Diff line
@@ -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 */
Loading