FTL: Add internal band state changes

Signed-off-by: Kozlowski Mateusz <mateusz.kozlowski@intel.com>
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: Icaecc4e77996919a23f70c1ffad15b783741fd5e
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13327
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Kozlowski Mateusz 2022-06-10 13:40:26 +02:00 committed by Jim Harris
parent 0f99700db9
commit 8c519d31bd
5 changed files with 116 additions and 0 deletions

View File

@ -59,6 +59,52 @@ ftl_band_free_md_entry(struct ftl_band *band)
p2l_map->band_dma_md = NULL;
}
static void
_ftl_band_set_free(struct ftl_band *band)
{
struct spdk_ftl_dev *dev = band->dev;
/* Add the band to the free band list */
TAILQ_INSERT_TAIL(&dev->free_bands, band, queue_entry);
dev->num_free++;
ftl_apply_limits(dev);
}
static void
_ftl_band_set_preparing(struct ftl_band *band)
{
struct spdk_ftl_dev *dev = band->dev;
/* Remove band from free list */
TAILQ_REMOVE(&dev->free_bands, band, queue_entry);
band->md->wr_cnt++;
assert(dev->num_free > 0);
dev->num_free--;
ftl_apply_limits(dev);
}
static void
_ftl_band_set_closed(struct ftl_band *band)
{
struct spdk_ftl_dev *dev = band->dev;
/* Set the state as free_md() checks for that */
band->md->state = FTL_BAND_STATE_CLOSED;
if (band->owner.state_change_fn) {
band->owner.state_change_fn(band);
}
/* Free the p2l map if there are no outstanding IOs */
ftl_band_release_p2l_map(band);
assert(band->p2l_map.ref_cnt == 0);
TAILQ_INSERT_TAIL(&dev->shut_bands, band, queue_entry);
}
ftl_addr
ftl_band_tail_md_addr(struct ftl_band *band)
{
@ -72,6 +118,46 @@ ftl_band_tail_md_addr(struct ftl_band *band)
return addr;
}
void
ftl_band_set_state(struct ftl_band *band, enum ftl_band_state state)
{
switch (state) {
case FTL_BAND_STATE_FREE:
assert(band->md->state == FTL_BAND_STATE_CLOSED);
_ftl_band_set_free(band);
band->md->p2l_map_checksum = 0;
break;
case FTL_BAND_STATE_PREP:
assert(band->md->state == FTL_BAND_STATE_FREE);
_ftl_band_set_preparing(band);
break;
case FTL_BAND_STATE_CLOSED:
if (band->md->state != FTL_BAND_STATE_CLOSED) {
assert(band->md->state == FTL_BAND_STATE_CLOSING);
_ftl_band_set_closed(band);
return; /* state can be changed asynchronously */
}
break;
case FTL_BAND_STATE_OPEN:
band->md->p2l_map_checksum = 0;
break;
case FTL_BAND_STATE_OPENING:
case FTL_BAND_STATE_FULL:
case FTL_BAND_STATE_CLOSING:
break;
default:
FTL_ERRLOG(band->dev, "Unknown band state, %u", state);
assert(false);
break;
}
band->md->state = state;
}
void
ftl_band_set_type(struct ftl_band *band, enum ftl_band_type type)
{

View File

@ -26,6 +26,15 @@ spdk_ftl_io_size(void)
return sizeof(struct ftl_io);
}
static void
ftl_band_erase(struct ftl_band *band)
{
assert(band->md->state == FTL_BAND_STATE_CLOSED ||
band->md->state == FTL_BAND_STATE_FREE);
ftl_band_set_state(band, FTL_BAND_STATE_PREP);
}
static size_t
ftl_get_limit(const struct spdk_ftl_dev *dev, int type)
{
@ -263,6 +272,20 @@ ftl_core_poller(void *ctx)
return SPDK_POLLER_IDLE;
}
struct ftl_band *
ftl_band_get_next_free(struct spdk_ftl_dev *dev)
{
struct ftl_band *band = NULL;
if (!TAILQ_EMPTY(&dev->free_bands)) {
band = TAILQ_FIRST(&dev->free_bands);
TAILQ_REMOVE(&dev->free_bands, band, queue_entry);
ftl_band_erase(band);
}
return band;
}
void *g_ftl_write_buf;
void *g_ftl_read_buf;

View File

@ -150,6 +150,8 @@ int ftl_io_channel_poll(void *arg);
struct ftl_io_channel *ftl_io_channel_get_ctx(struct spdk_io_channel *ioch);
struct ftl_band *ftl_band_get_next_free(struct spdk_ftl_dev *dev);
static inline uint64_t
ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
{

View File

@ -10,6 +10,7 @@
#include "ftl_io.h"
#include "ftl_core.h"
#include "ftl_band.h"
#include "ftl_debug.h"
void
@ -238,4 +239,5 @@ ftl_io_clear(struct ftl_io *io)
io->done = false;
io->status = 0;
io->flags = 0;
io->band = NULL;
}

View File

@ -88,6 +88,9 @@ struct ftl_io {
/* Offset within the iovec (in blocks) */
size_t iov_off;
/* Band this IO is being written to */
struct ftl_band *band;
/* Request status */
int status;