diff --git a/lib/ftl/ftl_reloc.c b/lib/ftl/ftl_reloc.c index f764ad30a..fd6ec493f 100644 --- a/lib/ftl/ftl_reloc.c +++ b/lib/ftl/ftl_reloc.c @@ -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; - 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) { 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);