lib/ftl: Consume whole underlying OCSSD device

Moving to zoned bdev API will not allow to setup
physical range of underlying device so we need to
remove such capabilities from ftl device.

Change-Id: Ia807a11e992a221fce906d4ab122a6c3b1391280
Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/467949
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
This commit is contained in:
Wojciech Malikowski 2019-09-10 07:42:21 -04:00 committed by Tomasz Zawadzki
parent 52a9661d94
commit aea8e78df2
11 changed files with 48 additions and 165 deletions

View File

@ -103,12 +103,6 @@ struct spdk_ftl_conf {
} nv_cache;
};
/* Range of parallel units (inclusive) */
struct spdk_ftl_punit_range {
unsigned int begin;
unsigned int end;
};
enum spdk_ftl_mode {
/* Create new device */
SPDK_FTL_MODE_CREATE = (1 << 0),
@ -131,8 +125,6 @@ struct spdk_ftl_dev_init_opts {
const struct spdk_ftl_conf *conf;
/* Device's name */
const char *name;
/* Parallel unit range */
struct spdk_ftl_punit_range range;
/* Mode flags */
unsigned int mode;
/* Device UUID (valid when restoring device from disk) */
@ -142,8 +134,6 @@ struct spdk_ftl_dev_init_opts {
struct spdk_ftl_attrs {
/* Device's UUID */
struct spdk_uuid uuid;
/* Parallel unit range */
struct spdk_ftl_punit_range range;
/* Number of logical blocks */
uint64_t lbk_cnt;
/* Logical block size */

View File

@ -192,10 +192,6 @@ ftl_anm_in_poller_range(struct ftl_anm_poller *poller,
return false;
}
if (!ftl_addr_in_range(dev, addr)) {
return false;
}
return true;
}

View File

@ -518,25 +518,16 @@ ftl_band_from_addr(struct spdk_ftl_dev *dev, struct ftl_addr addr)
struct ftl_zone *
ftl_band_zone_from_addr(struct ftl_band *band, struct ftl_addr addr)
{
struct spdk_ftl_dev *dev = band->dev;
unsigned int punit;
punit = ftl_addr_flatten_punit(dev, addr);
assert(punit < ftl_dev_num_punits(dev));
return &band->zone_buf[punit];
assert(addr.pu < ftl_dev_num_punits(band->dev));
return &band->zone_buf[addr.pu];
}
uint64_t
ftl_band_lbkoff_from_addr(struct ftl_band *band, struct ftl_addr addr)
{
struct spdk_ftl_dev *dev = band->dev;
unsigned int punit;
punit = ftl_addr_flatten_punit(dev, addr);
assert(addr.zone_id == band->id);
return punit * ftl_dev_lbks_in_zone(dev) + addr.offset;
assert(addr.pu < ftl_dev_num_punits(band->dev));
return addr.pu * ftl_dev_lbks_in_zone(band->dev) + addr.offset;
}
struct ftl_addr
@ -544,13 +535,11 @@ ftl_band_next_xfer_addr(struct ftl_band *band, struct ftl_addr addr, size_t num_
{
struct spdk_ftl_dev *dev = band->dev;
struct ftl_zone *zone;
unsigned int punit_num;
size_t num_xfers, num_stripes;
assert(addr.zone_id == band->id);
punit_num = ftl_addr_flatten_punit(dev, addr);
zone = &band->zone_buf[punit_num];
zone = ftl_band_zone_from_addr(band, addr);
num_lbks += (addr.offset % dev->xfer_size);
addr.offset -= (addr.offset % dev->xfer_size);
@ -633,7 +622,7 @@ ftl_band_addr_from_lbkoff(struct ftl_band *band, uint64_t lbkoff)
struct spdk_ftl_dev *dev = band->dev;
uint64_t punit;
punit = lbkoff / ftl_dev_lbks_in_zone(dev) + dev->range.begin;
punit = lbkoff / ftl_dev_lbks_in_zone(dev);
addr.offset = lbkoff % ftl_dev_lbks_in_zone(dev);
addr.zone_id = band->id;

View File

@ -1887,7 +1887,6 @@ spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *at
attrs->uuid = dev->uuid;
attrs->lbk_cnt = dev->num_lbas;
attrs->lbk_size = FTL_BLOCK_SIZE;
attrs->range = dev->range;
attrs->cache_bdev_desc = dev->nv_cache.bdev_desc;
attrs->num_zones = dev->geo.num_chk;
attrs->zone_size = dev->geo.clba;

View File

@ -183,8 +183,6 @@ struct spdk_ftl_dev {
/* Statistics */
struct ftl_stats stats;
/* Parallel unit range */
struct spdk_ftl_punit_range range;
/* Array of parallel units */
struct ftl_punit *punits;
@ -416,22 +414,6 @@ ftl_addr_from_packed(const struct spdk_ftl_dev *dev, struct ftl_addr p)
return addr;
}
static inline unsigned int
ftl_addr_flatten_punit(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
{
return addr.pu - dev->range.begin;
}
static inline int
ftl_addr_in_range(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
{
if (addr.pu >= dev->range.begin && addr.pu <= dev->range.end) {
return 1;
}
return 0;
}
#define _ftl_l2p_set(l2p, off, val, bits) \
__atomic_store_n(((uint##bits##_t *)(l2p)) + (off), val, __ATOMIC_SEQ_CST)
@ -492,7 +474,7 @@ ftl_dev_lbks_in_zone(const struct spdk_ftl_dev *dev)
static inline size_t
ftl_dev_num_punits(const struct spdk_ftl_dev *dev)
{
return dev->range.end - dev->range.begin + 1;
return dev->geo.num_pu * dev->geo.num_grp;
}
static inline uint64_t

View File

@ -54,9 +54,6 @@
#define FTL_INIT_TIMEOUT 30
#define FTL_NSID 1
#define ftl_range_intersect(s1, e1, s2, e2) \
((s1) <= (e2) && (s2) <= (e1))
struct ftl_admin_cmpl {
struct spdk_nvme_cpl status;
@ -167,41 +164,6 @@ ftl_check_conf(const struct spdk_ftl_conf *conf,
return 0;
}
static int
ftl_check_init_opts(const struct spdk_ftl_dev_init_opts *opts,
const struct spdk_ocssd_geometry_data *geo)
{
struct spdk_ftl_dev *dev;
size_t num_punits = geo->num_pu * geo->num_grp;
int rc = 0;
if (opts->range.begin > opts->range.end || opts->range.end >= num_punits) {
return -1;
}
if (ftl_check_conf(opts->conf, geo)) {
return -1;
}
pthread_mutex_lock(&g_ftl_queue_lock);
STAILQ_FOREACH(dev, &g_ftl_queue, stailq) {
if (spdk_nvme_transport_id_compare(&dev->trid, &opts->trid)) {
continue;
}
if (ftl_range_intersect(opts->range.begin, opts->range.end,
dev->range.begin, dev->range.end)) {
rc = -1;
goto out;
}
}
out:
pthread_mutex_unlock(&g_ftl_queue_lock);
return rc;
}
int
ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_addr addr,
struct spdk_ocssd_chunk_information_entry *info,
@ -401,7 +363,7 @@ out:
static int
ftl_dev_init_punits(struct spdk_ftl_dev *dev)
{
unsigned int i, punit;
size_t i;
dev->punits = calloc(ftl_dev_num_punits(dev), sizeof(*dev->punits));
if (!dev->punits) {
@ -410,10 +372,8 @@ ftl_dev_init_punits(struct spdk_ftl_dev *dev)
for (i = 0; i < ftl_dev_num_punits(dev); ++i) {
dev->punits[i].dev = dev;
punit = dev->range.begin + i;
dev->punits[i].start_addr.addr = 0;
dev->punits[i].start_addr.pu = punit;
dev->punits[i].start_addr.pu = i;
}
return 0;
@ -1126,10 +1086,7 @@ spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *_opts, spdk_ftl_init_fn c
goto fail_sync;
}
dev->range.begin = 0;
dev->range.end = dev->geo.num_pu * dev->geo.num_grp - 1;
if (ftl_check_init_opts(&opts, &dev->geo)) {
if (ftl_check_conf(opts.conf, &dev->geo)) {
SPDK_ERRLOG("Invalid device configuration\n");
goto fail_sync;
}

View File

@ -36,26 +36,22 @@
#include "spdk/ftl.h"
#include "ftl/ftl_core.h"
struct spdk_ftl_dev *test_init_ftl_dev(const struct spdk_ocssd_geometry_data *geo,
const struct spdk_ftl_punit_range *range);
struct spdk_ftl_dev *test_init_ftl_dev(const struct spdk_ocssd_geometry_data *geo);
struct ftl_band *test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id);
void test_free_ftl_dev(struct spdk_ftl_dev *dev);
void test_free_ftl_band(struct ftl_band *band);
uint64_t test_offset_from_addr(struct ftl_addr addr, struct ftl_band *band);
struct spdk_ftl_dev *
test_init_ftl_dev(const struct spdk_ocssd_geometry_data *geo,
const struct spdk_ftl_punit_range *range)
test_init_ftl_dev(const struct spdk_ocssd_geometry_data *geo)
{
struct spdk_ftl_dev *dev;
unsigned int punit;
dev = calloc(1, sizeof(*dev));
SPDK_CU_ASSERT_FATAL(dev != NULL);
dev->xfer_size = geo->ws_opt;
dev->geo = *geo;
dev->range = *range;
dev->core_thread.thread = spdk_thread_create("unit_test_thread", NULL);
spdk_set_thread(dev->core_thread.thread);
@ -71,9 +67,8 @@ test_init_ftl_dev(const struct spdk_ocssd_geometry_data *geo,
SPDK_CU_ASSERT_FATAL(dev->lba_pool != NULL);
for (size_t i = 0; i < ftl_dev_num_punits(dev); ++i) {
punit = range->begin + i;
dev->punits[i].dev = dev;
dev->punits[i].start_addr.pu = punit;
dev->punits[i].start_addr.pu = i;
}
LIST_INIT(&dev->free_bands);
@ -150,11 +145,8 @@ uint64_t
test_offset_from_addr(struct ftl_addr addr, struct ftl_band *band)
{
struct spdk_ftl_dev *dev = band->dev;
unsigned int punit;
/* TODO: ftl_addr_flatten_punit should return uint32_t */
punit = ftl_addr_flatten_punit(dev, addr);
CU_ASSERT_EQUAL(addr.zone_id, band->id);
return punit * ftl_dev_lbks_in_zone(dev) + addr.offset;
return addr.pu * ftl_dev_lbks_in_zone(dev) + addr.offset;
}

View File

@ -44,7 +44,7 @@
#define TEST_LBA 0x68676564
static struct spdk_ocssd_geometry_data g_geo = {
.num_grp = 4,
.num_grp = 3,
.num_pu = 3,
.num_chk = 1500,
.clba = 100,
@ -52,11 +52,6 @@ static struct spdk_ocssd_geometry_data g_geo = {
.ws_min = 4,
};
static struct spdk_ftl_punit_range g_range = {
.begin = 2,
.end = 9,
};
static struct spdk_ftl_dev *g_dev;
static struct ftl_band *g_band;
@ -65,7 +60,7 @@ setup_band(void)
{
int rc;
g_dev = test_init_ftl_dev(&g_geo, &g_range);
g_dev = test_init_ftl_dev(&g_geo);
g_band = test_init_ftl_band(g_dev, TEST_BAND_IDX);
rc = ftl_band_alloc_lba_map(g_band);
CU_ASSERT_EQUAL_FATAL(rc, 0);
@ -94,7 +89,7 @@ test_band_lbkoff_from_addr_base(void)
uint64_t offset, i, flat_lun = 0;
setup_band();
for (i = g_range.begin; i < g_range.end; ++i) {
for (i = 0; i < ftl_dev_num_punits(g_dev); ++i) {
addr = addr_from_punit(i);
addr.zone_id = TEST_BAND_IDX;
@ -112,7 +107,7 @@ test_band_lbkoff_from_addr_offset(void)
uint64_t offset, expect, i, j;
setup_band();
for (i = g_range.begin; i < g_range.end; ++i) {
for (i = 0; i < ftl_dev_num_punits(g_dev); ++i) {
for (j = 0; j < g_geo.clba; ++j) {
addr = addr_from_punit(i);
addr.zone_id = TEST_BAND_IDX;
@ -134,7 +129,7 @@ test_band_addr_from_lbkoff(void)
uint64_t offset, i, j;
setup_band();
for (i = g_range.begin; i < g_range.end; ++i) {
for (i = 0; i < ftl_dev_num_punits(g_dev); ++i) {
for (j = 0; j < g_geo.clba; ++j) {
expect = addr_from_punit(i);
expect.zone_id = TEST_BAND_IDX;
@ -158,7 +153,7 @@ test_band_set_addr(void)
setup_band();
lba_map = &g_band->lba_map;
addr = addr_from_punit(g_range.begin);
addr = addr_from_punit(0);
addr.zone_id = TEST_BAND_IDX;
CU_ASSERT_EQUAL(lba_map->num_vld, 0);
@ -191,7 +186,7 @@ test_invalidate_addr(void)
setup_band();
lba_map = &g_band->lba_map;
addr = addr_from_punit(g_range.begin);
addr = addr_from_punit(0);
addr.zone_id = TEST_BAND_IDX;
offset[0] = test_offset_from_addr(addr, g_band);
@ -224,7 +219,7 @@ test_next_xfer_addr(void)
setup_band();
/* Verify simple one lbk incremention */
addr = addr_from_punit(g_range.begin);
addr = addr_from_punit(0);
addr.zone_id = TEST_BAND_IDX;
addr.offset = 0;
expect = addr;
@ -234,41 +229,41 @@ test_next_xfer_addr(void)
CU_ASSERT_EQUAL(result.addr, expect.addr);
/* Verify jumping between zones */
expect = addr_from_punit(g_range.begin + 1);
expect = addr_from_punit(1);
expect.zone_id = TEST_BAND_IDX;
result = ftl_band_next_xfer_addr(g_band, addr, g_dev->xfer_size);
CU_ASSERT_EQUAL(result.addr, expect.addr);
/* Verify jumping works with unaligned offsets */
expect = addr_from_punit(g_range.begin + 1);
expect = addr_from_punit(1);
expect.zone_id = TEST_BAND_IDX;
expect.offset = 3;
result = ftl_band_next_xfer_addr(g_band, addr, g_dev->xfer_size + 3);
CU_ASSERT_EQUAL(result.addr, expect.addr);
/* Verify jumping from last zone to the first one */
expect = addr_from_punit(g_range.begin);
expect = addr_from_punit(0);
expect.zone_id = TEST_BAND_IDX;
expect.offset = g_dev->xfer_size;
addr = addr_from_punit(g_range.end);
addr = addr_from_punit(ftl_dev_num_punits(g_dev) - 1);
addr.zone_id = TEST_BAND_IDX;
result = ftl_band_next_xfer_addr(g_band, addr, g_dev->xfer_size);
CU_ASSERT_EQUAL(result.addr, expect.addr);
/* Verify jumping from last zone to the first one with unaligned offset */
expect = addr_from_punit(g_range.begin);
expect = addr_from_punit(0);
expect.zone_id = TEST_BAND_IDX;
expect.offset = g_dev->xfer_size + 2;
addr = addr_from_punit(g_range.end);
addr = addr_from_punit(ftl_dev_num_punits(g_dev) - 1);
addr.zone_id = TEST_BAND_IDX;
result = ftl_band_next_xfer_addr(g_band, addr, g_dev->xfer_size + 2);
CU_ASSERT_EQUAL(result.addr, expect.addr);
/* Verify large offset spanning across the whole band multiple times */
expect = addr_from_punit(g_range.begin);
expect = addr_from_punit(0);
expect.zone_id = TEST_BAND_IDX;
expect.offset = g_dev->xfer_size * 5 + 4;
addr = addr_from_punit(g_range.begin);
addr = addr_from_punit(0);
addr.zone_id = TEST_BAND_IDX;
addr.offset = g_dev->xfer_size * 2 + 1;
result = ftl_band_next_xfer_addr(g_band, addr, 3 * g_dev->xfer_size *
@ -279,10 +274,10 @@ test_next_xfer_addr(void)
g_band->zone_buf[1].state = SPDK_BDEV_ZONE_STATE_OFFLINE;
CIRCLEQ_REMOVE(&g_band->zones, &g_band->zone_buf[1], circleq);
g_band->num_zones--;
expect = addr_from_punit(g_range.begin + 2);
expect = addr_from_punit(2);
expect.zone_id = TEST_BAND_IDX;
expect.offset = g_dev->xfer_size * 5 + 4;
addr = addr_from_punit(g_range.begin);
addr = addr_from_punit(0);
addr.zone_id = TEST_BAND_IDX;
addr.offset = g_dev->xfer_size * 2 + 1;
result = ftl_band_next_xfer_addr(g_band, addr, 3 * g_dev->xfer_size *

View File

@ -48,19 +48,13 @@ static struct spdk_ocssd_geometry_data g_geo = {
.ws_min = 4,
};
static struct spdk_ftl_punit_range g_range = {
.begin = 2,
.end = 9,
};
static void
setup_band(struct ftl_band **band, const struct spdk_ocssd_geometry_data *geo,
const struct spdk_ftl_punit_range *range)
setup_band(struct ftl_band **band, const struct spdk_ocssd_geometry_data *geo)
{
int rc;
struct spdk_ftl_dev *dev;
dev = test_init_ftl_dev(geo, range);
dev = test_init_ftl_dev(geo);
*band = test_init_ftl_band(dev, 0);
rc = ftl_band_alloc_lba_map(*band);
SPDK_CU_ASSERT_FATAL(rc == 0);
@ -83,7 +77,7 @@ test_md_unpack(void)
struct ftl_band *band;
struct ftl_lba_map *lba_map;
setup_band(&band, &g_geo, &g_range);
setup_band(&band, &g_geo);
lba_map = &band->lba_map;
SPDK_CU_ASSERT_FATAL(lba_map->dma_buf);
@ -104,7 +98,7 @@ test_md_unpack_fail(void)
struct ftl_lba_map *lba_map;
struct ftl_md_hdr *hdr;
setup_band(&band, &g_geo, &g_range);
setup_band(&band, &g_geo);
lba_map = &band->lba_map;
SPDK_CU_ASSERT_FATAL(lba_map->dma_buf);

View File

@ -51,11 +51,6 @@ static struct spdk_ocssd_geometry_data g_geo = {
.ws_min = 4,
};
static struct spdk_ftl_punit_range g_range = {
.begin = 2,
.end = 9,
};
DEFINE_STUB(ftl_dev_tail_md_disk_size, size_t, (const struct spdk_ftl_dev *dev), 1);
DEFINE_STUB(ftl_addr_is_written, bool, (struct ftl_band *band, struct ftl_addr addr), true);
DEFINE_STUB_V(ftl_band_set_state, (struct ftl_band *band, enum ftl_band_state state));
@ -116,7 +111,7 @@ ftl_band_addr_from_lbkoff(struct ftl_band *band, uint64_t lbkoff)
struct spdk_ftl_dev *dev = band->dev;
uint64_t punit;
punit = lbkoff / ftl_dev_lbks_in_zone(dev) + dev->range.begin;
punit = lbkoff / ftl_dev_lbks_in_zone(dev);
addr.offset = lbkoff % ftl_dev_lbks_in_zone(dev);
addr.zone_id = band->id;
@ -204,13 +199,13 @@ add_to_active_queue(struct ftl_reloc *reloc, struct ftl_band_reloc *breloc)
static void
setup_reloc(struct spdk_ftl_dev **_dev, struct ftl_reloc **_reloc,
const struct spdk_ocssd_geometry_data *geo, const struct spdk_ftl_punit_range *range)
const struct spdk_ocssd_geometry_data *geo)
{
size_t i;
struct spdk_ftl_dev *dev;
struct ftl_reloc *reloc;
dev = test_init_ftl_dev(geo, range);
dev = test_init_ftl_dev(geo);
dev->conf.max_active_relocs = MAX_ACTIVE_RELOCS;
dev->conf.max_reloc_qdepth = MAX_RELOC_QDEPTH;
@ -269,7 +264,7 @@ test_reloc_iter_full(void)
struct ftl_band *band;
struct ftl_addr addr;
setup_reloc(&dev, &reloc, &g_geo, &g_range);
setup_reloc(&dev, &reloc, &g_geo);
dev->geo.clba = 100;
breloc = &reloc->brelocs[0];
@ -316,7 +311,7 @@ test_reloc_empty_band(void)
struct ftl_band_reloc *breloc;
struct ftl_band *band;
setup_reloc(&dev, &reloc, &g_geo, &g_range);
setup_reloc(&dev, &reloc, &g_geo);
breloc = &reloc->brelocs[0];
band = breloc->band;
@ -337,7 +332,7 @@ test_reloc_full_band(void)
struct ftl_band *band;
size_t num_moves, num_iters, num_lbk, i;
setup_reloc(&dev, &reloc, &g_geo, &g_range);
setup_reloc(&dev, &reloc, &g_geo);
breloc = &reloc->brelocs[0];
band = breloc->band;
@ -381,7 +376,7 @@ test_reloc_scatter_band(void)
struct ftl_band *band;
size_t num_iters, i;
setup_reloc(&dev, &reloc, &g_geo, &g_range);
setup_reloc(&dev, &reloc, &g_geo);
breloc = &reloc->brelocs[0];
band = breloc->band;
@ -419,7 +414,7 @@ test_reloc_zone(void)
struct ftl_band *band;
size_t num_io, num_iters, num_lbk, i;
setup_reloc(&dev, &reloc, &g_geo, &g_range);
setup_reloc(&dev, &reloc, &g_geo);
breloc = &reloc->brelocs[0];
band = breloc->band;
@ -465,7 +460,7 @@ test_reloc_single_lbk(void)
struct ftl_band *band;
#define TEST_RELOC_OFFSET 6
setup_reloc(&dev, &reloc, &g_geo, &g_range);
setup_reloc(&dev, &reloc, &g_geo);
breloc = &reloc->brelocs[0];
band = breloc->band;

View File

@ -49,11 +49,6 @@ static struct spdk_ocssd_geometry_data g_geo = {
.ws_min = 4,
};
static struct spdk_ftl_punit_range g_range = {
.begin = 2,
.end = 9,
};
#if defined(DEBUG)
DEFINE_STUB(ftl_band_validate_md, bool, (struct ftl_band *band), true);
#endif
@ -109,13 +104,12 @@ ftl_io_complete(struct ftl_io *io)
}
static void
setup_wptr_test(struct spdk_ftl_dev **dev, const struct spdk_ocssd_geometry_data *geo,
const struct spdk_ftl_punit_range *range)
setup_wptr_test(struct spdk_ftl_dev **dev, const struct spdk_ocssd_geometry_data *geo)
{
size_t i;
struct spdk_ftl_dev *t_dev;
t_dev = test_init_ftl_dev(geo, range);
t_dev = test_init_ftl_dev(geo);
for (i = 0; i < ftl_dev_num_bands(t_dev); ++i) {
test_init_ftl_band(t_dev, i);
@ -150,7 +144,7 @@ test_wptr(void)
size_t zone, lbk, offset, i;
int rc;
setup_wptr_test(&dev, &g_geo, &g_range);
setup_wptr_test(&dev, &g_geo);
xfer_size = dev->xfer_size;
ftl_add_wptr(dev);