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: Wojciech Malikowski <wojciech.malikowski@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/547 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
49de02ec4d
commit
c6bca349da
@ -78,6 +78,8 @@ struct ftl_reloc_move {
|
|||||||
|
|
||||||
/* IO associated with move */
|
/* IO associated with move */
|
||||||
struct ftl_io *io;
|
struct ftl_io *io;
|
||||||
|
|
||||||
|
STAILQ_ENTRY(ftl_reloc_move) entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ftl_band_reloc {
|
struct ftl_band_reloc {
|
||||||
@ -114,7 +116,7 @@ struct ftl_band_reloc {
|
|||||||
struct ftl_reloc_move *moves;
|
struct ftl_reloc_move *moves;
|
||||||
|
|
||||||
/* Move queue */
|
/* Move queue */
|
||||||
struct spdk_ring *move_queue;
|
STAILQ_HEAD(, ftl_reloc_move) move_queue;
|
||||||
|
|
||||||
TAILQ_ENTRY(ftl_band_reloc) entry;
|
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--;
|
breloc->num_outstanding--;
|
||||||
assert(status == 0);
|
assert(status == 0);
|
||||||
move->state = FTL_RELOC_STATE_WRITE;
|
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
|
static int
|
||||||
@ -234,7 +236,7 @@ ftl_reloc_prep(struct ftl_band_reloc *breloc)
|
|||||||
for (i = 0; i < reloc->max_qdepth; ++i) {
|
for (i = 0; i < reloc->max_qdepth; ++i) {
|
||||||
move = &breloc->moves[i];
|
move = &breloc->moves[i];
|
||||||
move->state = FTL_RELOC_STATE_READ;
|
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);
|
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
|
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->state = FTL_RELOC_STATE_READ_LBA_MAP;
|
||||||
move->io = NULL;
|
move->io = NULL;
|
||||||
spdk_ring_enqueue(breloc->move_queue, (void **)&move, 1, NULL);
|
STAILQ_INSERT_TAIL(&breloc->move_queue, move, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -479,7 +481,7 @@ ftl_reloc_write(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move)
|
|||||||
FTL_IO_WRITE, io_flags);
|
FTL_IO_WRITE, io_flags);
|
||||||
if (!move->io) {
|
if (!move->io) {
|
||||||
ftl_reloc_free_move(breloc, move);
|
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;
|
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);
|
move->io = ftl_reloc_io_init(breloc, move, ftl_reloc_read_cb, FTL_IO_READ, 0);
|
||||||
if (!move->io) {
|
if (!move->io) {
|
||||||
ftl_reloc_free_move(breloc, move);
|
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.");
|
SPDK_ERRLOG("Failed to initialize io for relocation.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -523,17 +525,21 @@ ftl_reloc_read(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move)
|
|||||||
static void
|
static void
|
||||||
ftl_reloc_process_moves(struct ftl_band_reloc *breloc)
|
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;
|
struct ftl_reloc_move *move;
|
||||||
|
STAILQ_HEAD(, ftl_reloc_move) move_queue;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
num_moves = spdk_ring_dequeue(breloc->move_queue, (void **)moves, reloc->max_qdepth);
|
/*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
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) {
|
switch (move->state) {
|
||||||
case FTL_RELOC_STATE_READ_LBA_MAP:
|
case FTL_RELOC_STATE_READ_LBA_MAP:
|
||||||
rc = ftl_reloc_read_lba_map(breloc, move);
|
rc = ftl_reloc_read_lba_map(breloc, move);
|
||||||
@ -559,7 +565,7 @@ ftl_reloc_process_moves(struct ftl_band_reloc *breloc)
|
|||||||
static bool
|
static bool
|
||||||
ftl_reloc_done(struct ftl_band_reloc *breloc)
|
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
|
static void
|
||||||
@ -632,13 +638,7 @@ ftl_band_reloc_init(struct ftl_reloc *reloc, struct ftl_band_reloc *breloc,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
breloc->move_queue = spdk_ring_create(SPDK_RING_TYPE_MP_SC,
|
STAILQ_INIT(&breloc->move_queue);
|
||||||
reloc->max_qdepth * 2,
|
|
||||||
SPDK_ENV_SOCKET_ID_ANY);
|
|
||||||
if (!breloc->move_queue) {
|
|
||||||
SPDK_ERRLOG("Failed to initialize reloc write queue");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
breloc->moves = calloc(reloc->max_qdepth, sizeof(*breloc->moves));
|
breloc->moves = calloc(reloc->max_qdepth, sizeof(*breloc->moves));
|
||||||
if (!breloc->moves) {
|
if (!breloc->moves) {
|
||||||
@ -651,28 +651,23 @@ ftl_band_reloc_init(struct ftl_reloc *reloc, struct ftl_band_reloc *breloc,
|
|||||||
static void
|
static void
|
||||||
ftl_band_reloc_free(struct ftl_band_reloc *breloc)
|
ftl_band_reloc_free(struct ftl_band_reloc *breloc)
|
||||||
{
|
{
|
||||||
struct ftl_reloc *reloc;
|
struct ftl_reloc_move *move;
|
||||||
struct ftl_reloc_move *moves[FTL_RELOC_MAX_MOVES] = {};
|
|
||||||
size_t i, num_moves;
|
|
||||||
|
|
||||||
if (!breloc) {
|
if (!breloc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(breloc->num_outstanding == 0);
|
assert(breloc->num_outstanding == 0);
|
||||||
reloc = breloc->parent;
|
|
||||||
|
|
||||||
/* Drain write queue if there is active band relocation during shutdown */
|
/* Drain write queue if there is active band relocation during shutdown */
|
||||||
if (breloc->state == FTL_BAND_RELOC_STATE_ACTIVE ||
|
if (breloc->state == FTL_BAND_RELOC_STATE_ACTIVE ||
|
||||||
breloc->state == FTL_BAND_RELOC_STATE_HIGH_PRIO) {
|
breloc->state == FTL_BAND_RELOC_STATE_HIGH_PRIO) {
|
||||||
assert(reloc->halt);
|
assert(breloc->parent->halt);
|
||||||
num_moves = spdk_ring_dequeue(breloc->move_queue, (void **)&moves, reloc->max_qdepth);
|
STAILQ_FOREACH(move, &breloc->move_queue, entry) {
|
||||||
for (i = 0; i < num_moves; ++i) {
|
ftl_reloc_free_move(breloc, move);
|
||||||
ftl_reloc_free_move(breloc, moves[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spdk_ring_free(breloc->move_queue);
|
|
||||||
spdk_bit_array_free(&breloc->reloc_map);
|
spdk_bit_array_free(&breloc->reloc_map);
|
||||||
free(breloc->iter.zone_offset);
|
free(breloc->iter.zone_offset);
|
||||||
free(breloc->moves);
|
free(breloc->moves);
|
||||||
|
Loading…
Reference in New Issue
Block a user