Commit c6bca349 authored by Wojciech Malikowski's avatar Wojciech Malikowski Committed by Tomasz Zawadzki
Browse files

lib/ftl: Replace reloc spdk_ring with STAILQ



Since relocation can be done only on core thread there is
no need for spdk_ring. Move queue size is limited by
reloc->max_qdepth so we are trying to iterate over all
move elements in move queue when processing band relocation.

Change-Id: Ic4cfaeeab4b5f3dd3e1dbd967908a3e6c9b3ed46
Signed-off-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/547


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 49de02ec
Loading
Loading
Loading
Loading
+27 −32
Original line number Diff line number Diff line
@@ -78,6 +78,8 @@ struct ftl_reloc_move {

	/* IO associated with move */
	struct ftl_io				*io;

	STAILQ_ENTRY(ftl_reloc_move)		entry;
};

struct ftl_band_reloc {
@@ -114,7 +116,7 @@ struct ftl_band_reloc {
	struct ftl_reloc_move			*moves;

	/* Move queue */
	struct spdk_ring			*move_queue;
	STAILQ_HEAD(, ftl_reloc_move)		move_queue;

	TAILQ_ENTRY(ftl_band_reloc)		entry;
};
@@ -196,7 +198,7 @@ ftl_reloc_read_lba_map_cb(struct ftl_io *io, void *arg, int status)
	breloc->num_outstanding--;
	assert(status == 0);
	move->state = FTL_RELOC_STATE_WRITE;
	spdk_ring_enqueue(breloc->move_queue, (void **)&move, 1, NULL);
	STAILQ_INSERT_TAIL(&breloc->move_queue, move, entry);
}

static int
@@ -234,7 +236,7 @@ ftl_reloc_prep(struct ftl_band_reloc *breloc)
	for (i = 0; i < reloc->max_qdepth; ++i) {
		move = &breloc->moves[i];
		move->state = FTL_RELOC_STATE_READ;
		spdk_ring_enqueue(breloc->move_queue, (void **)&move, 1, NULL);
		STAILQ_INSERT_TAIL(&breloc->move_queue, move, entry);
	}
}

@@ -270,7 +272,7 @@ ftl_reloc_write_cb(struct ftl_io *io, void *arg, int status)
	}

	ftl_reloc_free_move(breloc, move);
	spdk_ring_enqueue(breloc->move_queue, (void **)&move, 1, NULL);
	STAILQ_INSERT_TAIL(&breloc->move_queue, move, entry);
}

static void
@@ -292,7 +294,7 @@ ftl_reloc_read_cb(struct ftl_io *io, void *arg, int status)

	move->state = FTL_RELOC_STATE_READ_LBA_MAP;
	move->io = NULL;
	spdk_ring_enqueue(breloc->move_queue, (void **)&move, 1, NULL);
	STAILQ_INSERT_TAIL(&breloc->move_queue, move, entry);
}

static void
@@ -479,7 +481,7 @@ ftl_reloc_write(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move)
					     FTL_IO_WRITE, io_flags);
		if (!move->io) {
			ftl_reloc_free_move(breloc, move);
			spdk_ring_enqueue(breloc->move_queue, (void **)&move, 1, NULL);
			STAILQ_INSERT_TAIL(&breloc->move_queue, move, entry);
			return -ENOMEM;
		}
	}
@@ -510,7 +512,7 @@ ftl_reloc_read(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move)
	move->io = ftl_reloc_io_init(breloc, move, ftl_reloc_read_cb, FTL_IO_READ, 0);
	if (!move->io) {
		ftl_reloc_free_move(breloc, move);
		spdk_ring_enqueue(breloc->move_queue, (void **)&move, 1, NULL);
		STAILQ_INSERT_TAIL(&breloc->move_queue, move, entry);
		SPDK_ERRLOG("Failed to initialize io for relocation.");
		return -1;
	}
@@ -523,17 +525,21 @@ ftl_reloc_read(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move)
static void
ftl_reloc_process_moves(struct ftl_band_reloc *breloc)
{
	int rc = 0;
	size_t i, num_moves;
	struct ftl_reloc_move *moves[FTL_RELOC_MAX_MOVES] = {0};
	struct ftl_reloc *reloc = breloc->parent;
	struct ftl_reloc_move *move;
	STAILQ_HEAD(, ftl_reloc_move) move_queue;
	int rc = 0;

	/*
	 * When IO allocation fails, we do not want to retry immediately so keep moves on
	 * temporary queue
	 */
	STAILQ_INIT(&move_queue);
	STAILQ_SWAP(&breloc->move_queue, &move_queue, ftl_reloc_move);

	num_moves = spdk_ring_dequeue(breloc->move_queue, (void **)moves, reloc->max_qdepth);
	while (!STAILQ_EMPTY(&move_queue)) {
		move = STAILQ_FIRST(&move_queue);
		STAILQ_REMOVE_HEAD(&move_queue, entry);

	for (i = 0; i < num_moves; ++i) {
		move = moves[i];
		assert(move != NULL);
		switch (move->state) {
		case FTL_RELOC_STATE_READ_LBA_MAP:
			rc = ftl_reloc_read_lba_map(breloc, move);
@@ -559,7 +565,7 @@ ftl_reloc_process_moves(struct ftl_band_reloc *breloc)
static bool
ftl_reloc_done(struct ftl_band_reloc *breloc)
{
	return !breloc->num_outstanding && !spdk_ring_count(breloc->move_queue);
	return !breloc->num_outstanding && STAILQ_EMPTY(&breloc->move_queue);
}

static void
@@ -632,13 +638,7 @@ ftl_band_reloc_init(struct ftl_reloc *reloc, struct ftl_band_reloc *breloc,
		return -1;
	}

	breloc->move_queue = spdk_ring_create(SPDK_RING_TYPE_MP_SC,
					      reloc->max_qdepth * 2,
					      SPDK_ENV_SOCKET_ID_ANY);
	if (!breloc->move_queue) {
		SPDK_ERRLOG("Failed to initialize reloc write queue");
		return -1;
	}
	STAILQ_INIT(&breloc->move_queue);

	breloc->moves = calloc(reloc->max_qdepth, sizeof(*breloc->moves));
	if (!breloc->moves) {
@@ -651,28 +651,23 @@ ftl_band_reloc_init(struct ftl_reloc *reloc, struct ftl_band_reloc *breloc,
static void
ftl_band_reloc_free(struct ftl_band_reloc *breloc)
{
	struct ftl_reloc *reloc;
	struct ftl_reloc_move *moves[FTL_RELOC_MAX_MOVES] = {};
	size_t i, num_moves;
	struct ftl_reloc_move *move;

	if (!breloc) {
		return;
	}

	assert(breloc->num_outstanding == 0);
	reloc = breloc->parent;

	/* Drain write queue if there is active band relocation during shutdown */
	if (breloc->state == FTL_BAND_RELOC_STATE_ACTIVE ||
	    breloc->state == FTL_BAND_RELOC_STATE_HIGH_PRIO) {
		assert(reloc->halt);
		num_moves = spdk_ring_dequeue(breloc->move_queue, (void **)&moves, reloc->max_qdepth);
		for (i = 0; i < num_moves; ++i) {
			ftl_reloc_free_move(breloc, moves[i]);
		assert(breloc->parent->halt);
		STAILQ_FOREACH(move, &breloc->move_queue, entry) {
			ftl_reloc_free_move(breloc, move);
		}
	}

	spdk_ring_free(breloc->move_queue);
	spdk_bit_array_free(&breloc->reloc_map);
	free(breloc->iter.zone_offset);
	free(breloc->moves);