lib/ftl: Replace ftl_ppa struct with ftl_addr
FTL working on top of zoned bdev doesn't need physical page address (PPA) anymore. ftl_ppa was replaced with ftl_addr which represents zoned device addressing schema. Change-Id: Ied5750a7ab2f4ce42067ff3e69c1f26f85f5022a Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/467633 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
This commit is contained in:
parent
748785c2a9
commit
e47e16d3a4
@ -31,13 +31,13 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FTL_PPA_H
|
||||
#define FTL_PPA_H
|
||||
#ifndef FTL_ADDR_H
|
||||
#define FTL_ADDR_H
|
||||
|
||||
#include "spdk/stdinc.h"
|
||||
|
||||
/* Marks PPA as invalid */
|
||||
#define FTL_PPA_INVALID (-1)
|
||||
/* Marks address as invalid */
|
||||
#define FTL_ADDR_INVALID (-1)
|
||||
/* Marks LBA as invalid */
|
||||
#define FTL_LBA_INVALID ((uint64_t)-1)
|
||||
/* Smallest data unit size */
|
||||
@ -50,7 +50,7 @@
|
||||
/* - packed version of the two formats above (can be only used when the */
|
||||
/* raw address can be represented in less than 32 bits) */
|
||||
/* Packed format is used, when possible, to avoid wasting RAM on the L2P table. */
|
||||
struct ftl_ppa {
|
||||
struct ftl_addr {
|
||||
union {
|
||||
struct {
|
||||
uint64_t offset : 32;
|
||||
@ -98,4 +98,4 @@ struct ftl_ppa_fmt {
|
||||
unsigned int grp_mask;
|
||||
};
|
||||
|
||||
#endif /* FTL_PPA_H */
|
||||
#endif /* FTL_ADDR_H */
|
@ -118,7 +118,7 @@ ftl_anm_log_range(struct spdk_ocssd_chunk_notification_entry *log)
|
||||
}
|
||||
|
||||
static struct ftl_anm_event *
|
||||
ftl_anm_event_alloc(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
|
||||
ftl_anm_event_alloc(struct spdk_ftl_dev *dev, struct ftl_addr addr,
|
||||
enum ftl_anm_range range, size_t num_lbks)
|
||||
{
|
||||
struct ftl_anm_event *event;
|
||||
@ -129,7 +129,7 @@ ftl_anm_event_alloc(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
|
||||
}
|
||||
|
||||
event->dev = dev;
|
||||
event->ppa = ppa;
|
||||
event->addr = addr;
|
||||
|
||||
switch (range) {
|
||||
case FTL_ANM_RANGE_LBK:
|
||||
@ -152,7 +152,7 @@ ftl_anm_process_log(struct ftl_anm_poller *poller,
|
||||
struct spdk_ocssd_chunk_notification_entry *log)
|
||||
{
|
||||
struct ftl_anm_event *event;
|
||||
struct ftl_ppa ppa = ftl_ppa_addr_unpack(poller->dev, log->lba);
|
||||
struct ftl_addr addr = ftl_addr_addr_unpack(poller->dev, log->lba);
|
||||
struct spdk_ftl_dev *dev = poller->dev;
|
||||
enum ftl_anm_range range = ftl_anm_log_range(log);
|
||||
int i, num_bands = 1;
|
||||
@ -160,19 +160,19 @@ ftl_anm_process_log(struct ftl_anm_poller *poller,
|
||||
num_bands = range != FTL_ANM_RANGE_PU ? 1 : ftl_dev_num_bands(dev);
|
||||
|
||||
for (i = 0; i < num_bands; ++i) {
|
||||
struct ftl_zone *zone = ftl_band_zone_from_ppa(&dev->bands[i], ppa);
|
||||
struct ftl_zone *zone = ftl_band_zone_from_addr(&dev->bands[i], addr);
|
||||
|
||||
if (zone->state == SPDK_BDEV_ZONE_STATE_OFFLINE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
event = ftl_anm_event_alloc(dev, ppa, range, log->nlb);
|
||||
event = ftl_anm_event_alloc(dev, addr, range, log->nlb);
|
||||
if (!event) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
poller->fn(event);
|
||||
ppa.zone_id++;
|
||||
addr.zone_id++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -183,16 +183,16 @@ ftl_anm_in_poller_range(struct ftl_anm_poller *poller,
|
||||
struct spdk_ocssd_chunk_notification_entry *log)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = poller->dev;
|
||||
struct ftl_ppa ppa = ftl_ppa_addr_unpack(dev, log->lba);
|
||||
struct ftl_addr addr = ftl_addr_addr_unpack(dev, log->lba);
|
||||
char buf[128];
|
||||
|
||||
if (ppa.zone_id >= ftl_dev_num_bands(dev)) {
|
||||
SPDK_ERRLOG("ANM log contains invalid @ppa: %s\n",
|
||||
ftl_ppa2str(ppa, buf, sizeof(buf)));
|
||||
if (addr.zone_id >= ftl_dev_num_bands(dev)) {
|
||||
SPDK_ERRLOG("ANM log contains invalid @addr: %s\n",
|
||||
ftl_addr2str(addr, buf, sizeof(buf)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ftl_ppa_in_range(dev, ppa)) {
|
||||
if (!ftl_addr_in_range(dev, addr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
#define FTL_ANM_H
|
||||
|
||||
#include "spdk/thread.h"
|
||||
#include "ftl_ppa.h"
|
||||
#include "ftl_addr.h"
|
||||
|
||||
struct ftl_nvme_ctrlr;
|
||||
struct ftl_anm_event;
|
||||
@ -54,8 +54,8 @@ struct ftl_anm_event {
|
||||
/* Owner device */
|
||||
struct spdk_ftl_dev *dev;
|
||||
|
||||
/* Start PPA */
|
||||
struct ftl_ppa ppa;
|
||||
/* First block address */
|
||||
struct ftl_addr addr;
|
||||
|
||||
/* Number of logical blocks */
|
||||
size_t num_lbks;
|
||||
|
@ -382,10 +382,10 @@ ftl_unpack_head_md(struct ftl_band *band)
|
||||
return FTL_MD_SUCCESS;
|
||||
}
|
||||
|
||||
struct ftl_ppa
|
||||
ftl_band_tail_md_ppa(struct ftl_band *band)
|
||||
struct ftl_addr
|
||||
ftl_band_tail_md_addr(struct ftl_band *band)
|
||||
{
|
||||
struct ftl_ppa ppa = {};
|
||||
struct ftl_addr addr = {};
|
||||
struct ftl_zone *zone;
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
size_t xfer_size = dev->xfer_size;
|
||||
@ -393,7 +393,7 @@ ftl_band_tail_md_ppa(struct ftl_band *band)
|
||||
size_t i;
|
||||
|
||||
if (spdk_unlikely(!band->num_zones)) {
|
||||
return ftl_to_ppa(FTL_PPA_INVALID);
|
||||
return ftl_to_addr(FTL_ADDR_INVALID);
|
||||
}
|
||||
|
||||
/* Metadata should be aligned to xfer size */
|
||||
@ -404,26 +404,26 @@ ftl_band_tail_md_ppa(struct ftl_band *band)
|
||||
zone = ftl_band_next_zone(band, zone);
|
||||
}
|
||||
|
||||
ppa.offset = (num_req / band->num_zones) * xfer_size;
|
||||
ppa.zone_id = band->id;
|
||||
ppa.pu = zone->punit->start_ppa.pu;
|
||||
addr.offset = (num_req / band->num_zones) * xfer_size;
|
||||
addr.zone_id = band->id;
|
||||
addr.pu = zone->punit->start_addr.pu;
|
||||
|
||||
return ppa;
|
||||
return addr;
|
||||
}
|
||||
|
||||
struct ftl_ppa
|
||||
ftl_band_head_md_ppa(struct ftl_band *band)
|
||||
struct ftl_addr
|
||||
ftl_band_head_md_addr(struct ftl_band *band)
|
||||
{
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
|
||||
if (spdk_unlikely(!band->num_zones)) {
|
||||
return ftl_to_ppa(FTL_PPA_INVALID);
|
||||
return ftl_to_addr(FTL_ADDR_INVALID);
|
||||
}
|
||||
|
||||
ppa = CIRCLEQ_FIRST(&band->zones)->punit->start_ppa;
|
||||
ppa.zone_id = band->id;
|
||||
addr = CIRCLEQ_FIRST(&band->zones)->punit->start_addr;
|
||||
addr.zone_id = band->id;
|
||||
|
||||
return ppa;
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -455,14 +455,14 @@ ftl_band_set_state(struct ftl_band *band, enum ftl_band_state state)
|
||||
}
|
||||
|
||||
void
|
||||
ftl_band_set_addr(struct ftl_band *band, uint64_t lba, struct ftl_ppa ppa)
|
||||
ftl_band_set_addr(struct ftl_band *band, uint64_t lba, struct ftl_addr addr)
|
||||
{
|
||||
struct ftl_lba_map *lba_map = &band->lba_map;
|
||||
uint64_t offset;
|
||||
|
||||
assert(lba != FTL_LBA_INVALID);
|
||||
|
||||
offset = ftl_band_lbkoff_from_ppa(band, ppa);
|
||||
offset = ftl_band_lbkoff_from_addr(band, addr);
|
||||
pthread_spin_lock(&lba_map->lock);
|
||||
|
||||
lba_map->num_vld++;
|
||||
@ -509,51 +509,51 @@ ftl_band_user_lbks(const struct ftl_band *band)
|
||||
}
|
||||
|
||||
struct ftl_band *
|
||||
ftl_band_from_ppa(struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
ftl_band_from_addr(struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
assert(ppa.zone_id < ftl_dev_num_bands(dev));
|
||||
return &dev->bands[ppa.zone_id];
|
||||
assert(addr.zone_id < ftl_dev_num_bands(dev));
|
||||
return &dev->bands[addr.zone_id];
|
||||
}
|
||||
|
||||
struct ftl_zone *
|
||||
ftl_band_zone_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
|
||||
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_ppa_flatten_punit(dev, ppa);
|
||||
punit = ftl_addr_flatten_punit(dev, addr);
|
||||
assert(punit < ftl_dev_num_punits(dev));
|
||||
|
||||
return &band->zone_buf[punit];
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ftl_band_lbkoff_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
|
||||
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_ppa_flatten_punit(dev, ppa);
|
||||
assert(ppa.zone_id == band->id);
|
||||
punit = ftl_addr_flatten_punit(dev, addr);
|
||||
assert(addr.zone_id == band->id);
|
||||
|
||||
return punit * ftl_dev_lbks_in_zone(dev) + ppa.offset;
|
||||
return punit * ftl_dev_lbks_in_zone(dev) + addr.offset;
|
||||
}
|
||||
|
||||
struct ftl_ppa
|
||||
ftl_band_next_xfer_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t num_lbks)
|
||||
struct ftl_addr
|
||||
ftl_band_next_xfer_addr(struct ftl_band *band, struct ftl_addr addr, size_t num_lbks)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
struct ftl_zone *zone;
|
||||
unsigned int punit_num;
|
||||
size_t num_xfers, num_stripes;
|
||||
|
||||
assert(ppa.zone_id == band->id);
|
||||
assert(addr.zone_id == band->id);
|
||||
|
||||
punit_num = ftl_ppa_flatten_punit(dev, ppa);
|
||||
punit_num = ftl_addr_flatten_punit(dev, addr);
|
||||
zone = &band->zone_buf[punit_num];
|
||||
|
||||
num_lbks += (ppa.offset % dev->xfer_size);
|
||||
ppa.offset -= (ppa.offset % dev->xfer_size);
|
||||
num_lbks += (addr.offset % dev->xfer_size);
|
||||
addr.offset -= (addr.offset % dev->xfer_size);
|
||||
|
||||
#if defined(DEBUG)
|
||||
/* Check that the number of zones has not been changed */
|
||||
@ -568,11 +568,11 @@ ftl_band_next_xfer_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t num_lbk
|
||||
#endif
|
||||
assert(band->num_zones != 0);
|
||||
num_stripes = (num_lbks / dev->xfer_size) / band->num_zones;
|
||||
ppa.offset += num_stripes * dev->xfer_size;
|
||||
addr.offset += num_stripes * dev->xfer_size;
|
||||
num_lbks -= num_stripes * dev->xfer_size * band->num_zones;
|
||||
|
||||
if (ppa.offset > ftl_dev_lbks_in_zone(dev)) {
|
||||
return ftl_to_ppa(FTL_PPA_INVALID);
|
||||
if (addr.offset > ftl_dev_lbks_in_zone(dev)) {
|
||||
return ftl_to_addr(FTL_ADDR_INVALID);
|
||||
}
|
||||
|
||||
num_xfers = num_lbks / dev->xfer_size;
|
||||
@ -580,42 +580,42 @@ ftl_band_next_xfer_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t num_lbk
|
||||
/* When the last zone is reached the lbk part of the address */
|
||||
/* needs to be increased by xfer_size */
|
||||
if (ftl_band_zone_is_last(band, zone)) {
|
||||
ppa.offset += dev->xfer_size;
|
||||
if (ppa.offset > ftl_dev_lbks_in_zone(dev)) {
|
||||
return ftl_to_ppa(FTL_PPA_INVALID);
|
||||
addr.offset += dev->xfer_size;
|
||||
if (addr.offset > ftl_dev_lbks_in_zone(dev)) {
|
||||
return ftl_to_addr(FTL_ADDR_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
zone = ftl_band_next_operational_zone(band, zone);
|
||||
assert(zone);
|
||||
ppa.pu = zone->start_ppa.pu;
|
||||
addr.pu = zone->start_addr.pu;
|
||||
|
||||
num_lbks -= dev->xfer_size;
|
||||
}
|
||||
|
||||
if (num_lbks) {
|
||||
ppa.offset += num_lbks;
|
||||
if (ppa.offset > ftl_dev_lbks_in_zone(dev)) {
|
||||
return ftl_to_ppa(FTL_PPA_INVALID);
|
||||
addr.offset += num_lbks;
|
||||
if (addr.offset > ftl_dev_lbks_in_zone(dev)) {
|
||||
return ftl_to_addr(FTL_ADDR_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
return ppa;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static size_t
|
||||
ftl_xfer_offset_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
|
||||
ftl_xfer_offset_from_addr(struct ftl_band *band, struct ftl_addr addr)
|
||||
{
|
||||
struct ftl_zone *zone, *current_zone;
|
||||
unsigned int punit_offset = 0;
|
||||
size_t off, num_stripes, xfer_size = band->dev->xfer_size;
|
||||
|
||||
assert(ppa.zone_id == band->id);
|
||||
assert(addr.zone_id == band->id);
|
||||
|
||||
num_stripes = (ppa.offset / xfer_size) * band->num_zones;
|
||||
off = ppa.offset % xfer_size;
|
||||
num_stripes = (addr.offset / xfer_size) * band->num_zones;
|
||||
off = addr.offset % xfer_size;
|
||||
|
||||
current_zone = ftl_band_zone_from_ppa(band, ppa);
|
||||
current_zone = ftl_band_zone_from_addr(band, addr);
|
||||
CIRCLEQ_FOREACH(zone, &band->zones, circleq) {
|
||||
if (current_zone == zone) {
|
||||
break;
|
||||
@ -626,27 +626,27 @@ ftl_xfer_offset_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
|
||||
return xfer_size * (num_stripes + punit_offset) + off;
|
||||
}
|
||||
|
||||
struct ftl_ppa
|
||||
ftl_band_ppa_from_lbkoff(struct ftl_band *band, uint64_t lbkoff)
|
||||
struct ftl_addr
|
||||
ftl_band_addr_from_lbkoff(struct ftl_band *band, uint64_t lbkoff)
|
||||
{
|
||||
struct ftl_ppa ppa = { .addr = 0 };
|
||||
struct ftl_addr addr = { .addr = 0 };
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
uint64_t punit;
|
||||
|
||||
punit = lbkoff / ftl_dev_lbks_in_zone(dev) + dev->range.begin;
|
||||
|
||||
ppa.offset = lbkoff % ftl_dev_lbks_in_zone(dev);
|
||||
ppa.zone_id = band->id;
|
||||
ppa.pu = punit;
|
||||
addr.offset = lbkoff % ftl_dev_lbks_in_zone(dev);
|
||||
addr.zone_id = band->id;
|
||||
addr.pu = punit;
|
||||
|
||||
return ppa;
|
||||
return addr;
|
||||
}
|
||||
|
||||
struct ftl_ppa
|
||||
ftl_band_next_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t offset)
|
||||
struct ftl_addr
|
||||
ftl_band_next_addr(struct ftl_band *band, struct ftl_addr addr, size_t offset)
|
||||
{
|
||||
uint64_t lbkoff = ftl_band_lbkoff_from_ppa(band, ppa);
|
||||
return ftl_band_ppa_from_lbkoff(band, lbkoff + offset);
|
||||
uint64_t lbkoff = ftl_band_lbkoff_from_addr(band, addr);
|
||||
return ftl_band_addr_from_lbkoff(band, lbkoff + offset);
|
||||
}
|
||||
|
||||
void
|
||||
@ -711,7 +711,7 @@ ftl_read_md_cb(struct ftl_io *io, void *arg, int status)
|
||||
}
|
||||
|
||||
static struct ftl_md_io *
|
||||
ftl_io_init_md_read(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
|
||||
ftl_io_init_md_read(struct spdk_ftl_dev *dev, struct ftl_addr addr,
|
||||
struct ftl_band *band, size_t lbk_cnt, void *buf,
|
||||
ftl_io_fn fn, ftl_md_pack_fn pack_fn, ftl_io_fn cb_fn, void *cb_ctx)
|
||||
{
|
||||
@ -722,7 +722,7 @@ ftl_io_init_md_read(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
|
||||
.rwb_batch = NULL,
|
||||
.band = band,
|
||||
.size = sizeof(*io),
|
||||
.flags = FTL_IO_MD | FTL_IO_PPA_MODE,
|
||||
.flags = FTL_IO_MD | FTL_IO_PHYSICAL_MODE,
|
||||
.type = FTL_IO_READ,
|
||||
.lbk_cnt = lbk_cnt,
|
||||
.cb_fn = fn,
|
||||
@ -734,7 +734,7 @@ ftl_io_init_md_read(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
io->io.ppa = ppa;
|
||||
io->io.addr = addr;
|
||||
io->pack_fn = pack_fn;
|
||||
io->cb_fn = cb_fn;
|
||||
io->cb_ctx = cb_ctx;
|
||||
@ -752,7 +752,7 @@ ftl_io_init_md_write(struct spdk_ftl_dev *dev, struct ftl_band *band,
|
||||
.rwb_batch = NULL,
|
||||
.band = band,
|
||||
.size = sizeof(struct ftl_io),
|
||||
.flags = FTL_IO_MD | FTL_IO_PPA_MODE,
|
||||
.flags = FTL_IO_MD | FTL_IO_PHYSICAL_MODE,
|
||||
.type = FTL_IO_WRITE,
|
||||
.lbk_cnt = lbk_cnt,
|
||||
.cb_fn = cb,
|
||||
@ -804,17 +804,17 @@ ftl_band_write_tail_md(struct ftl_band *band, ftl_io_fn cb)
|
||||
ftl_pack_tail_md, cb);
|
||||
}
|
||||
|
||||
static struct ftl_ppa
|
||||
ftl_band_lba_map_ppa(struct ftl_band *band, size_t offset)
|
||||
static struct ftl_addr
|
||||
ftl_band_lba_map_addr(struct ftl_band *band, size_t offset)
|
||||
{
|
||||
return ftl_band_next_xfer_ppa(band, band->tail_md_ppa,
|
||||
return ftl_band_next_xfer_addr(band, band->tail_md_addr,
|
||||
ftl_tail_md_hdr_num_lbks() +
|
||||
ftl_vld_map_num_lbks(band->dev) +
|
||||
offset);
|
||||
}
|
||||
|
||||
static int
|
||||
ftl_band_read_md(struct ftl_band *band, size_t lbk_cnt, struct ftl_ppa start_ppa,
|
||||
ftl_band_read_md(struct ftl_band *band, size_t lbk_cnt, struct ftl_addr start_addr,
|
||||
void *buf, ftl_io_fn fn, ftl_md_pack_fn pack_fn, ftl_io_fn cb_fn, void *cb_ctx)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
@ -824,7 +824,7 @@ ftl_band_read_md(struct ftl_band *band, size_t lbk_cnt, struct ftl_ppa start_ppa
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
io = ftl_io_init_md_read(dev, start_ppa, band, lbk_cnt, buf, fn, pack_fn, cb_fn, cb_ctx);
|
||||
io = ftl_io_init_md_read(dev, start_addr, band, lbk_cnt, buf, fn, pack_fn, cb_fn, cb_ctx);
|
||||
if (!io) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -834,9 +834,9 @@ ftl_band_read_md(struct ftl_band *band, size_t lbk_cnt, struct ftl_ppa start_ppa
|
||||
}
|
||||
|
||||
int
|
||||
ftl_band_read_tail_md(struct ftl_band *band, struct ftl_ppa ppa, ftl_io_fn cb_fn, void *cb_ctx)
|
||||
ftl_band_read_tail_md(struct ftl_band *band, struct ftl_addr addr, ftl_io_fn cb_fn, void *cb_ctx)
|
||||
{
|
||||
return ftl_band_read_md(band, ftl_tail_md_num_lbks(band->dev), ppa, band->lba_map.dma_buf,
|
||||
return ftl_band_read_md(band, ftl_tail_md_num_lbks(band->dev), addr, band->lba_map.dma_buf,
|
||||
ftl_read_md_cb, ftl_unpack_tail_md, cb_fn, cb_ctx);
|
||||
}
|
||||
|
||||
@ -895,12 +895,12 @@ ftl_process_lba_map_requests(struct spdk_ftl_dev *dev, struct ftl_lba_map *lba_m
|
||||
}
|
||||
|
||||
static size_t
|
||||
ftl_lba_map_offset_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
|
||||
ftl_lba_map_offset_from_addr(struct ftl_band *band, struct ftl_addr addr)
|
||||
{
|
||||
size_t offset;
|
||||
struct ftl_ppa start_ppa = ftl_band_lba_map_ppa(band, 0);
|
||||
struct ftl_addr start_addr = ftl_band_lba_map_addr(band, 0);
|
||||
|
||||
offset = ftl_xfer_offset_from_ppa(band, ppa) - ftl_xfer_offset_from_ppa(band, start_ppa);
|
||||
offset = ftl_xfer_offset_from_addr(band, addr) - ftl_xfer_offset_from_addr(band, start_addr);
|
||||
assert(offset < ftl_lba_map_num_lbks(band->dev));
|
||||
|
||||
return offset;
|
||||
@ -912,7 +912,7 @@ ftl_read_lba_map_cb(struct ftl_io *io, void *arg, int status)
|
||||
struct ftl_lba_map *lba_map = &io->band->lba_map;
|
||||
uint64_t lbk_off;
|
||||
|
||||
lbk_off = ftl_lba_map_offset_from_ppa(io->band, io->ppa);
|
||||
lbk_off = ftl_lba_map_offset_from_addr(io->band, io->addr);
|
||||
assert(lbk_off + io->lbk_cnt <= ftl_lba_map_num_lbks(io->dev));
|
||||
|
||||
if (!status) {
|
||||
@ -996,7 +996,7 @@ ftl_band_read_lba_map(struct ftl_band *band, size_t offset, size_t lba_cnt,
|
||||
ftl_lba_map_set_segment_state(lba_map, lbk_off, num_read,
|
||||
FTL_LBA_MAP_SEG_PENDING);
|
||||
|
||||
rc = ftl_band_read_md(band, num_read, ftl_band_lba_map_ppa(band, lbk_off),
|
||||
rc = ftl_band_read_md(band, num_read, ftl_band_lba_map_addr(band, lbk_off),
|
||||
(char *)band->lba_map.map + lbk_off * FTL_BLOCK_SIZE,
|
||||
ftl_read_lba_map_cb, NULL, cb_fn, cb_ctx);
|
||||
if (rc) {
|
||||
@ -1024,7 +1024,7 @@ ftl_band_read_head_md(struct ftl_band *band, ftl_io_fn cb_fn, void *cb_ctx)
|
||||
{
|
||||
return ftl_band_read_md(band,
|
||||
ftl_head_md_num_lbks(band->dev),
|
||||
ftl_band_head_md_ppa(band),
|
||||
ftl_band_head_md_addr(band),
|
||||
band->lba_map.dma_buf,
|
||||
ftl_read_md_cb,
|
||||
ftl_unpack_head_md,
|
||||
@ -1046,13 +1046,13 @@ ftl_erase_fail(struct ftl_io *io, int status)
|
||||
struct ftl_band *band = io->band;
|
||||
char buf[128];
|
||||
|
||||
SPDK_ERRLOG("Erase failed @ppa: %s, status: %d\n",
|
||||
ftl_ppa2str(io->ppa, buf, sizeof(buf)), status);
|
||||
SPDK_ERRLOG("Erase failed @addr: %s, status: %d\n",
|
||||
ftl_addr2str(io->addr, buf, sizeof(buf)), status);
|
||||
|
||||
zone = ftl_band_zone_from_ppa(band, io->ppa);
|
||||
zone = ftl_band_zone_from_addr(band, io->addr);
|
||||
zone->state = SPDK_BDEV_ZONE_STATE_OFFLINE;
|
||||
ftl_band_remove_zone(band, zone);
|
||||
band->tail_md_ppa = ftl_band_tail_md_ppa(band);
|
||||
band->tail_md_addr = ftl_band_tail_md_addr(band);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1064,7 +1064,7 @@ ftl_band_erase_cb(struct ftl_io *io, void *ctx, int status)
|
||||
ftl_erase_fail(io, status);
|
||||
return;
|
||||
}
|
||||
zone = ftl_band_zone_from_ppa(io->band, io->ppa);
|
||||
zone = ftl_band_zone_from_addr(io->band, io->addr);
|
||||
zone->state = SPDK_BDEV_ZONE_STATE_EMPTY;
|
||||
zone->write_offset = 0;
|
||||
}
|
||||
@ -1092,7 +1092,7 @@ ftl_band_erase(struct ftl_band *band)
|
||||
break;
|
||||
}
|
||||
|
||||
io->ppa = zone->start_ppa;
|
||||
io->addr = zone->start_addr;
|
||||
rc = ftl_io_erase(io);
|
||||
if (rc) {
|
||||
assert(0);
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "spdk/bdev_zone.h"
|
||||
|
||||
#include "ftl_io.h"
|
||||
#include "ftl_ppa.h"
|
||||
#include "ftl_addr.h"
|
||||
#include "ftl_io.h"
|
||||
|
||||
/* Number of LBAs that could be stored in a single block */
|
||||
@ -59,8 +59,8 @@ struct ftl_zone {
|
||||
/* Current logical block's offset */
|
||||
uint64_t write_offset;
|
||||
|
||||
/* First PPA */
|
||||
struct ftl_ppa start_ppa;
|
||||
/* First logical block of a zone */
|
||||
struct ftl_addr start_addr;
|
||||
|
||||
/* Pointer to parallel unit */
|
||||
struct ftl_punit *punit;
|
||||
@ -178,8 +178,8 @@ struct ftl_band {
|
||||
/* Number of defrag cycles */
|
||||
uint64_t wr_cnt;
|
||||
|
||||
/* End metadata start ppa */
|
||||
struct ftl_ppa tail_md_ppa;
|
||||
/* End metadata start addr */
|
||||
struct ftl_addr tail_md_addr;
|
||||
|
||||
/* Bitmap of all bands that have its data moved onto this band */
|
||||
struct spdk_bit_array *reloc_bitmap;
|
||||
@ -195,8 +195,8 @@ struct ftl_band {
|
||||
STAILQ_ENTRY(ftl_band) prio_stailq;
|
||||
};
|
||||
|
||||
uint64_t ftl_band_lbkoff_from_ppa(struct ftl_band *band, struct ftl_ppa ppa);
|
||||
struct ftl_ppa ftl_band_ppa_from_lbkoff(struct ftl_band *band, uint64_t lbkoff);
|
||||
uint64_t ftl_band_lbkoff_from_addr(struct ftl_band *band, struct ftl_addr addr);
|
||||
struct ftl_addr ftl_band_addr_from_lbkoff(struct ftl_band *band, uint64_t lbkoff);
|
||||
void ftl_band_set_state(struct ftl_band *band, enum ftl_band_state state);
|
||||
size_t ftl_band_age(const struct ftl_band *band);
|
||||
void ftl_band_acquire_lba_map(struct ftl_band *band);
|
||||
@ -206,25 +206,25 @@ void ftl_band_release_lba_map(struct ftl_band *band);
|
||||
int ftl_band_read_lba_map(struct ftl_band *band,
|
||||
size_t offset, size_t lba_cnt,
|
||||
ftl_io_fn cb_fn, void *cb_ctx);
|
||||
struct ftl_ppa ftl_band_next_xfer_ppa(struct ftl_band *band, struct ftl_ppa ppa,
|
||||
struct ftl_addr ftl_band_next_xfer_addr(struct ftl_band *band, struct ftl_addr addr,
|
||||
size_t num_lbks);
|
||||
struct ftl_ppa ftl_band_next_ppa(struct ftl_band *band, struct ftl_ppa ppa,
|
||||
struct ftl_addr ftl_band_next_addr(struct ftl_band *band, struct ftl_addr addr,
|
||||
size_t offset);
|
||||
size_t ftl_band_num_usable_lbks(const struct ftl_band *band);
|
||||
size_t ftl_band_user_lbks_left(const struct ftl_band *band, size_t offset);
|
||||
size_t ftl_band_user_lbks(const struct ftl_band *band);
|
||||
void ftl_band_set_addr(struct ftl_band *band, uint64_t lba,
|
||||
struct ftl_ppa ppa);
|
||||
struct ftl_band *ftl_band_from_ppa(struct spdk_ftl_dev *dev, struct ftl_ppa ppa);
|
||||
struct ftl_zone *ftl_band_zone_from_ppa(struct ftl_band *band, struct ftl_ppa);
|
||||
struct ftl_addr addr);
|
||||
struct ftl_band *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);
|
||||
void ftl_band_md_clear(struct ftl_band *band);
|
||||
int ftl_band_read_tail_md(struct ftl_band *band, struct ftl_ppa,
|
||||
int ftl_band_read_tail_md(struct ftl_band *band, struct ftl_addr,
|
||||
ftl_io_fn cb_fn, void *cb_ctx);
|
||||
int ftl_band_read_head_md(struct ftl_band *band, ftl_io_fn cb_fn, void *cb_ctx);
|
||||
int ftl_band_write_tail_md(struct ftl_band *band, ftl_io_fn cb);
|
||||
int ftl_band_write_head_md(struct ftl_band *band, ftl_io_fn cb);
|
||||
struct ftl_ppa ftl_band_tail_md_ppa(struct ftl_band *band);
|
||||
struct ftl_ppa ftl_band_head_md_ppa(struct ftl_band *band);
|
||||
struct ftl_addr ftl_band_tail_md_addr(struct ftl_band *band);
|
||||
struct ftl_addr ftl_band_head_md_addr(struct ftl_band *band);
|
||||
void ftl_band_write_failed(struct ftl_band *band);
|
||||
int ftl_band_full(struct ftl_band *band, size_t offset);
|
||||
int ftl_band_erase(struct ftl_band *band);
|
||||
|
@ -65,8 +65,8 @@ struct ftl_wptr {
|
||||
/* Owner device */
|
||||
struct spdk_ftl_dev *dev;
|
||||
|
||||
/* Current PPA */
|
||||
struct ftl_ppa ppa;
|
||||
/* Current address */
|
||||
struct ftl_addr addr;
|
||||
|
||||
/* Band currently being written to */
|
||||
struct ftl_band *band;
|
||||
@ -85,7 +85,8 @@ struct ftl_wptr {
|
||||
|
||||
/*
|
||||
* If setup in direct mode, there will be no offset or band state update after IO.
|
||||
* The PPA is not assigned by wptr, and is instead taken directly from the request.
|
||||
* The zoned bdev address is not assigned by wptr, and is instead taken directly
|
||||
* from the request.
|
||||
*/
|
||||
bool direct_mode;
|
||||
|
||||
@ -224,8 +225,8 @@ ftl_md_write_fail(struct ftl_io *io, int status)
|
||||
wptr = ftl_wptr_from_band(band);
|
||||
assert(wptr);
|
||||
|
||||
SPDK_ERRLOG("Metadata write failed @ppa: %s, status: %d\n",
|
||||
ftl_ppa2str(wptr->ppa, buf, sizeof(buf)), status);
|
||||
SPDK_ERRLOG("Metadata write failed @addr: %s, status: %d\n",
|
||||
ftl_addr2str(wptr->addr, buf, sizeof(buf)), status);
|
||||
|
||||
ftl_halt_writes(io->dev, band);
|
||||
}
|
||||
@ -278,28 +279,29 @@ ftl_md_write_cb(struct ftl_io *io, void *arg, int status)
|
||||
}
|
||||
|
||||
static int
|
||||
ftl_ppa_read_next_ppa(struct ftl_io *io, struct ftl_ppa *ppa)
|
||||
ftl_read_next_physical_addr(struct ftl_io *io, struct ftl_addr *addr)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = io->dev;
|
||||
size_t lbk_cnt, max_lbks;
|
||||
|
||||
assert(ftl_io_mode_ppa(io));
|
||||
assert(ftl_io_mode_physical(io));
|
||||
assert(io->iov_pos < io->iov_cnt);
|
||||
|
||||
if (io->pos == 0) {
|
||||
*ppa = io->ppa;
|
||||
*addr = io->addr;
|
||||
} else {
|
||||
*ppa = ftl_band_next_xfer_ppa(io->band, io->ppa, io->pos);
|
||||
*addr = ftl_band_next_xfer_addr(io->band, io->addr, io->pos);
|
||||
}
|
||||
|
||||
assert(!ftl_ppa_invalid(*ppa));
|
||||
assert(!ftl_addr_invalid(*addr));
|
||||
|
||||
/* Metadata has to be read in the way it's written (jumping across */
|
||||
/* the zones in xfer_size increments) */
|
||||
if (io->flags & FTL_IO_MD) {
|
||||
max_lbks = dev->xfer_size - (ppa->offset % dev->xfer_size);
|
||||
max_lbks = dev->xfer_size - (addr->offset % dev->xfer_size);
|
||||
lbk_cnt = spdk_min(ftl_io_iovec_len_left(io), max_lbks);
|
||||
assert(ppa->offset / dev->xfer_size == (ppa->offset + lbk_cnt - 1) / dev->xfer_size);
|
||||
assert(addr->offset / dev->xfer_size ==
|
||||
(addr->offset + lbk_cnt - 1) / dev->xfer_size);
|
||||
} else {
|
||||
lbk_cnt = ftl_io_iovec_len_left(io);
|
||||
}
|
||||
@ -338,25 +340,25 @@ ftl_submit_erase(struct ftl_io *io)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = io->dev;
|
||||
struct ftl_band *band = io->band;
|
||||
struct ftl_ppa ppa = io->ppa;
|
||||
struct ftl_addr addr = io->addr;
|
||||
struct ftl_zone *zone;
|
||||
uint64_t ppa_packed;
|
||||
uint64_t addr_packed;
|
||||
int rc = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < io->lbk_cnt; ++i) {
|
||||
if (i != 0) {
|
||||
zone = ftl_band_next_zone(band, ftl_band_zone_from_ppa(band, ppa));
|
||||
zone = ftl_band_next_zone(band, ftl_band_zone_from_addr(band, addr));
|
||||
assert(zone->state == SPDK_BDEV_ZONE_STATE_CLOSED);
|
||||
ppa = zone->start_ppa;
|
||||
addr = zone->start_addr;
|
||||
}
|
||||
|
||||
assert(ppa.offset == 0);
|
||||
ppa_packed = ftl_ppa_addr_pack(dev, ppa);
|
||||
assert(addr.offset == 0);
|
||||
addr_packed = ftl_addr_addr_pack(dev, addr);
|
||||
|
||||
ftl_trace_submission(dev, io, ppa, 1);
|
||||
ftl_trace_submission(dev, io, addr, 1);
|
||||
rc = spdk_nvme_ocssd_ns_cmd_vector_reset(dev->ns, ftl_get_write_qpair(dev),
|
||||
&ppa_packed, 1, NULL, ftl_io_cmpl_cb, io);
|
||||
&addr_packed, 1, NULL, ftl_io_cmpl_cb, io);
|
||||
if (spdk_unlikely(rc)) {
|
||||
ftl_io_fail(io, rc);
|
||||
SPDK_ERRLOG("Vector reset failed with status: %d\n", rc);
|
||||
@ -474,7 +476,7 @@ ftl_wptr_init(struct ftl_band *band)
|
||||
wptr->dev = dev;
|
||||
wptr->band = band;
|
||||
wptr->zone = CIRCLEQ_FIRST(&band->zones);
|
||||
wptr->ppa = wptr->zone->start_ppa;
|
||||
wptr->addr = wptr->zone->start_addr;
|
||||
TAILQ_INIT(&wptr->pending_queue);
|
||||
|
||||
return wptr;
|
||||
@ -580,13 +582,13 @@ ftl_wptr_advance(struct ftl_wptr *wptr, size_t xfer_size)
|
||||
}
|
||||
|
||||
wptr->zone->busy = true;
|
||||
wptr->ppa = ftl_band_next_xfer_ppa(band, wptr->ppa, xfer_size);
|
||||
wptr->addr = ftl_band_next_xfer_addr(band, wptr->addr, xfer_size);
|
||||
wptr->zone = ftl_band_next_operational_zone(band, wptr->zone);
|
||||
|
||||
assert(!ftl_ppa_invalid(wptr->ppa));
|
||||
assert(!ftl_addr_invalid(wptr->addr));
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "wptr: pu:%d zone:%d, lbk:%u\n",
|
||||
wptr->ppa.pu, wptr->ppa.zone_id, wptr->ppa.offset);
|
||||
wptr->addr.pu, wptr->addr.zone_id, wptr->addr.offset);
|
||||
|
||||
if (wptr->offset >= next_thld && !dev->next_band) {
|
||||
dev->next_band = ftl_next_write_band(dev);
|
||||
@ -681,15 +683,15 @@ ftl_get_limit(const struct spdk_ftl_dev *dev, int type)
|
||||
static bool
|
||||
ftl_cache_lba_valid(struct spdk_ftl_dev *dev, struct ftl_rwb_entry *entry)
|
||||
{
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
|
||||
/* If the LBA is invalid don't bother checking the md and l2p */
|
||||
if (spdk_unlikely(entry->lba == FTL_LBA_INVALID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ppa = ftl_l2p_get(dev, entry->lba);
|
||||
if (!(ftl_ppa_cached(ppa) && ppa.cache_offset == entry->pos)) {
|
||||
addr = ftl_l2p_get(dev, entry->lba);
|
||||
if (!(ftl_addr_cached(addr) && addr.cache_offset == entry->pos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -706,13 +708,13 @@ ftl_evict_cache_entry(struct spdk_ftl_dev *dev, struct ftl_rwb_entry *entry)
|
||||
}
|
||||
|
||||
/* If the l2p wasn't updated and still points at the entry, fill it with the */
|
||||
/* on-disk PPA and clear the cache status bit. Otherwise, skip the l2p update */
|
||||
/* on-disk address and clear the cache status bit. Otherwise, skip the l2p update */
|
||||
/* and just clear the cache status. */
|
||||
if (!ftl_cache_lba_valid(dev, entry)) {
|
||||
goto clear;
|
||||
}
|
||||
|
||||
ftl_l2p_set(dev, entry->lba, entry->ppa);
|
||||
ftl_l2p_set(dev, entry->lba, entry->addr);
|
||||
clear:
|
||||
ftl_rwb_entry_invalidate(entry);
|
||||
unlock:
|
||||
@ -748,7 +750,7 @@ ftl_rwb_pad(struct spdk_ftl_dev *dev, size_t size)
|
||||
}
|
||||
|
||||
entry->lba = FTL_LBA_INVALID;
|
||||
entry->ppa = ftl_to_ppa(FTL_PPA_INVALID);
|
||||
entry->addr = ftl_to_addr(FTL_ADDR_INVALID);
|
||||
memset(entry->data, 0, FTL_BLOCK_SIZE);
|
||||
ftl_rwb_push(entry);
|
||||
}
|
||||
@ -842,13 +844,13 @@ apply:
|
||||
}
|
||||
|
||||
static int
|
||||
ftl_invalidate_addr_unlocked(struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
ftl_invalidate_addr_unlocked(struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
struct ftl_band *band = ftl_band_from_ppa(dev, ppa);
|
||||
struct ftl_band *band = ftl_band_from_addr(dev, addr);
|
||||
struct ftl_lba_map *lba_map = &band->lba_map;
|
||||
uint64_t offset;
|
||||
|
||||
offset = ftl_band_lbkoff_from_ppa(band, ppa);
|
||||
offset = ftl_band_lbkoff_from_addr(band, addr);
|
||||
|
||||
/* The bit might be already cleared if two writes are scheduled to the */
|
||||
/* same LBA at the same time */
|
||||
@ -863,16 +865,16 @@ ftl_invalidate_addr_unlocked(struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
}
|
||||
|
||||
int
|
||||
ftl_invalidate_addr(struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
ftl_invalidate_addr(struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
struct ftl_band *band;
|
||||
int rc;
|
||||
|
||||
assert(!ftl_ppa_cached(ppa));
|
||||
band = ftl_band_from_ppa(dev, ppa);
|
||||
assert(!ftl_addr_cached(addr));
|
||||
band = ftl_band_from_addr(dev, addr);
|
||||
|
||||
pthread_spin_lock(&band->lba_map.lock);
|
||||
rc = ftl_invalidate_addr_unlocked(dev, ppa);
|
||||
rc = ftl_invalidate_addr_unlocked(dev, addr);
|
||||
pthread_spin_unlock(&band->lba_map.lock);
|
||||
|
||||
return rc;
|
||||
@ -900,19 +902,19 @@ ftl_add_to_retry_queue(struct ftl_io *io)
|
||||
}
|
||||
|
||||
static int
|
||||
ftl_ppa_cache_read(struct ftl_io *io, uint64_t lba,
|
||||
struct ftl_ppa ppa, void *buf)
|
||||
ftl_cache_read(struct ftl_io *io, uint64_t lba,
|
||||
struct ftl_addr addr, void *buf)
|
||||
{
|
||||
struct ftl_rwb *rwb = io->dev->rwb;
|
||||
struct ftl_rwb_entry *entry;
|
||||
struct ftl_ppa nppa;
|
||||
struct ftl_addr naddr;
|
||||
int rc = 0;
|
||||
|
||||
entry = ftl_rwb_entry_from_offset(rwb, ppa.cache_offset);
|
||||
entry = ftl_rwb_entry_from_offset(rwb, addr.cache_offset);
|
||||
pthread_spin_lock(&entry->lock);
|
||||
|
||||
nppa = ftl_l2p_get(io->dev, lba);
|
||||
if (ppa.addr != nppa.addr) {
|
||||
naddr = ftl_l2p_get(io->dev, lba);
|
||||
if (addr.addr != naddr.addr) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -924,24 +926,24 @@ out:
|
||||
}
|
||||
|
||||
static int
|
||||
ftl_lba_read_next_ppa(struct ftl_io *io, struct ftl_ppa *ppa)
|
||||
ftl_read_next_logical_addr(struct ftl_io *io, struct ftl_addr *addr)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = io->dev;
|
||||
struct ftl_ppa next_ppa;
|
||||
struct ftl_addr next_addr;
|
||||
size_t i;
|
||||
|
||||
*ppa = ftl_l2p_get(dev, ftl_io_current_lba(io));
|
||||
*addr = ftl_l2p_get(dev, ftl_io_current_lba(io));
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Read ppa:%lx, lba:%lu\n",
|
||||
ppa->addr, ftl_io_current_lba(io));
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Read addr:%lx, lba:%lu\n",
|
||||
addr->addr, ftl_io_current_lba(io));
|
||||
|
||||
/* If the PPA is invalid, skip it (the buffer should already be zero'ed) */
|
||||
if (ftl_ppa_invalid(*ppa)) {
|
||||
/* If the address is invalid, skip it (the buffer should already be zero'ed) */
|
||||
if (ftl_addr_invalid(*addr)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (ftl_ppa_cached(*ppa)) {
|
||||
if (!ftl_ppa_cache_read(io, ftl_io_current_lba(io), *ppa, ftl_io_iovec_addr(io))) {
|
||||
if (ftl_addr_cached(*addr)) {
|
||||
if (!ftl_cache_read(io, ftl_io_current_lba(io), *addr, ftl_io_iovec_addr(io))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -950,13 +952,13 @@ ftl_lba_read_next_ppa(struct ftl_io *io, struct ftl_ppa *ppa)
|
||||
}
|
||||
|
||||
for (i = 1; i < ftl_io_iovec_len_left(io); ++i) {
|
||||
next_ppa = ftl_l2p_get(dev, ftl_io_get_lba(io, io->pos + i));
|
||||
next_addr = ftl_l2p_get(dev, ftl_io_get_lba(io, io->pos + i));
|
||||
|
||||
if (ftl_ppa_invalid(next_ppa) || ftl_ppa_cached(next_ppa)) {
|
||||
if (ftl_addr_invalid(next_addr) || ftl_addr_cached(next_addr)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ftl_ppa_addr_pack(dev, *ppa) + i != ftl_ppa_addr_pack(dev, next_ppa)) {
|
||||
if (ftl_addr_addr_pack(dev, *addr) + i != ftl_addr_addr_pack(dev, next_addr)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -968,16 +970,16 @@ static int
|
||||
ftl_submit_read(struct ftl_io *io)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = io->dev;
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
int rc = 0, lbk_cnt;
|
||||
|
||||
assert(LIST_EMPTY(&io->children));
|
||||
|
||||
while (io->pos < io->lbk_cnt) {
|
||||
if (ftl_io_mode_ppa(io)) {
|
||||
lbk_cnt = rc = ftl_ppa_read_next_ppa(io, &ppa);
|
||||
if (ftl_io_mode_physical(io)) {
|
||||
lbk_cnt = rc = ftl_read_next_physical_addr(io, &addr);
|
||||
} else {
|
||||
lbk_cnt = rc = ftl_lba_read_next_ppa(io, &ppa);
|
||||
lbk_cnt = rc = ftl_read_next_logical_addr(io, &addr);
|
||||
}
|
||||
|
||||
/* We might need to retry the read from scratch (e.g. */
|
||||
@ -998,10 +1000,10 @@ ftl_submit_read(struct ftl_io *io)
|
||||
|
||||
assert(lbk_cnt > 0);
|
||||
|
||||
ftl_trace_submission(dev, io, ppa, lbk_cnt);
|
||||
ftl_trace_submission(dev, io, addr, lbk_cnt);
|
||||
rc = spdk_nvme_ns_cmd_read(dev->ns, ftl_get_read_qpair(dev),
|
||||
ftl_io_iovec_addr(io),
|
||||
ftl_ppa_addr_pack(io->dev, ppa), lbk_cnt,
|
||||
ftl_addr_addr_pack(io->dev, addr), lbk_cnt,
|
||||
ftl_io_cmpl_cb, io, 0);
|
||||
if (spdk_unlikely(rc)) {
|
||||
if (rc == -ENOMEM) {
|
||||
@ -1148,7 +1150,7 @@ ftl_nv_cache_submit_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
|
||||
struct ftl_nv_cache *nv_cache = &io->dev->nv_cache;
|
||||
|
||||
if (spdk_unlikely(!success)) {
|
||||
SPDK_ERRLOG("Non-volatile cache write failed at %"PRIx64"\n", io->ppa.addr);
|
||||
SPDK_ERRLOG("Non-volatile cache write failed at %"PRIx64"\n", io->addr.addr);
|
||||
io->status = -EIO;
|
||||
}
|
||||
|
||||
@ -1175,14 +1177,14 @@ ftl_submit_nv_cache(void *ctx)
|
||||
thread = spdk_io_channel_get_thread(io->ioch);
|
||||
|
||||
rc = spdk_bdev_write_blocks_with_md(nv_cache->bdev_desc, ioch->cache_ioch,
|
||||
ftl_io_iovec_addr(io), io->md, io->ppa.addr,
|
||||
ftl_io_iovec_addr(io), io->md, io->addr.addr,
|
||||
io->lbk_cnt, ftl_nv_cache_submit_cb, io);
|
||||
if (rc == -ENOMEM) {
|
||||
spdk_thread_send_msg(thread, ftl_submit_nv_cache, io);
|
||||
return;
|
||||
} else if (rc) {
|
||||
SPDK_ERRLOG("Write to persistent cache failed: %s (%"PRIu64", %"PRIu64")\n",
|
||||
spdk_strerror(-rc), io->ppa.addr, io->lbk_cnt);
|
||||
spdk_strerror(-rc), io->addr.addr, io->lbk_cnt);
|
||||
spdk_mempool_put(nv_cache->md_pool, io->md);
|
||||
io->status = -EIO;
|
||||
ftl_io_complete(io);
|
||||
@ -1238,8 +1240,8 @@ _ftl_write_nv_cache(void *ctx)
|
||||
}
|
||||
|
||||
/* Reserve area on the write buffer cache */
|
||||
child->ppa.addr = ftl_reserve_nv_cache(&dev->nv_cache, &num_lbks, &phase);
|
||||
if (child->ppa.addr == FTL_LBA_INVALID) {
|
||||
child->addr.addr = ftl_reserve_nv_cache(&dev->nv_cache, &num_lbks, &phase);
|
||||
if (child->addr.addr == FTL_LBA_INVALID) {
|
||||
spdk_mempool_put(dev->nv_cache.md_pool, child->md);
|
||||
ftl_io_free(child);
|
||||
spdk_thread_send_msg(thread, _ftl_write_nv_cache, io);
|
||||
@ -1319,16 +1321,16 @@ ftl_write_fail(struct ftl_io *io, int status)
|
||||
|
||||
entry = ftl_rwb_batch_first_entry(batch);
|
||||
|
||||
band = ftl_band_from_ppa(io->dev, entry->ppa);
|
||||
SPDK_ERRLOG("Write failed @ppa: %s, status: %d\n",
|
||||
ftl_ppa2str(entry->ppa, buf, sizeof(buf)), status);
|
||||
band = ftl_band_from_addr(io->dev, entry->addr);
|
||||
SPDK_ERRLOG("Write failed @addr: %s, status: %d\n",
|
||||
ftl_addr2str(entry->addr, buf, sizeof(buf)), status);
|
||||
|
||||
/* Close the band and, halt wptr and defrag */
|
||||
ftl_halt_writes(dev, band);
|
||||
|
||||
ftl_rwb_foreach(entry, batch) {
|
||||
/* Invalidate meta set by process_writes() */
|
||||
ftl_invalidate_addr(dev, entry->ppa);
|
||||
ftl_invalidate_addr(dev, entry->addr);
|
||||
}
|
||||
|
||||
/* Reset the batch back to the the RWB to resend it later */
|
||||
@ -1361,8 +1363,8 @@ ftl_write_cb(struct ftl_io *io, void *arg, int status)
|
||||
band->num_reloc_blocks--;
|
||||
}
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write ppa:%lu, lba:%lu\n",
|
||||
entry->ppa.addr, entry->lba);
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write addr:%lu, lba:%lu\n",
|
||||
entry->addr.addr, entry->lba);
|
||||
}
|
||||
|
||||
ftl_process_flush(dev, batch);
|
||||
@ -1380,70 +1382,70 @@ ftl_update_rwb_stats(struct spdk_ftl_dev *dev, const struct ftl_rwb_entry *entry
|
||||
|
||||
static void
|
||||
ftl_update_l2p(struct spdk_ftl_dev *dev, const struct ftl_rwb_entry *entry,
|
||||
struct ftl_ppa ppa)
|
||||
struct ftl_addr addr)
|
||||
{
|
||||
struct ftl_ppa prev_ppa;
|
||||
struct ftl_addr prev_addr;
|
||||
struct ftl_rwb_entry *prev;
|
||||
struct ftl_band *band;
|
||||
int valid;
|
||||
|
||||
prev_ppa = ftl_l2p_get(dev, entry->lba);
|
||||
if (ftl_ppa_invalid(prev_ppa)) {
|
||||
ftl_l2p_set(dev, entry->lba, ppa);
|
||||
prev_addr = ftl_l2p_get(dev, entry->lba);
|
||||
if (ftl_addr_invalid(prev_addr)) {
|
||||
ftl_l2p_set(dev, entry->lba, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the L2P's PPA is different than what we expected we don't need to */
|
||||
/* If the L2P's physical address is different than what we expected we don't need to */
|
||||
/* do anything (someone's already overwritten our data). */
|
||||
if (ftl_rwb_entry_weak(entry) && !ftl_ppa_cmp(prev_ppa, entry->ppa)) {
|
||||
if (ftl_rwb_entry_weak(entry) && !ftl_addr_cmp(prev_addr, entry->addr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ftl_ppa_cached(prev_ppa)) {
|
||||
if (ftl_addr_cached(prev_addr)) {
|
||||
assert(!ftl_rwb_entry_weak(entry));
|
||||
prev = ftl_rwb_entry_from_offset(dev->rwb, prev_ppa.cache_offset);
|
||||
prev = ftl_rwb_entry_from_offset(dev->rwb, prev_addr.cache_offset);
|
||||
pthread_spin_lock(&prev->lock);
|
||||
|
||||
/* Re-read the L2P under the lock to protect against updates */
|
||||
/* to this LBA from other threads */
|
||||
prev_ppa = ftl_l2p_get(dev, entry->lba);
|
||||
prev_addr = ftl_l2p_get(dev, entry->lba);
|
||||
|
||||
/* If the entry is no longer in cache, another write has been */
|
||||
/* scheduled in the meantime, so we have to invalidate its LBA */
|
||||
if (!ftl_ppa_cached(prev_ppa)) {
|
||||
ftl_invalidate_addr(dev, prev_ppa);
|
||||
if (!ftl_addr_cached(prev_addr)) {
|
||||
ftl_invalidate_addr(dev, prev_addr);
|
||||
}
|
||||
|
||||
/* If previous entry is part of cache, remove and invalidate it */
|
||||
if (ftl_rwb_entry_valid(prev)) {
|
||||
ftl_invalidate_addr(dev, prev->ppa);
|
||||
ftl_invalidate_addr(dev, prev->addr);
|
||||
ftl_rwb_entry_invalidate(prev);
|
||||
}
|
||||
|
||||
ftl_l2p_set(dev, entry->lba, ppa);
|
||||
ftl_l2p_set(dev, entry->lba, addr);
|
||||
pthread_spin_unlock(&prev->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Lock the band containing previous PPA. This assures atomic changes to */
|
||||
/* Lock the band containing previous physical address. This assures atomic changes to */
|
||||
/* the L2P as wall as metadata. The valid bits in metadata are used to */
|
||||
/* check weak writes validity. */
|
||||
band = ftl_band_from_ppa(dev, prev_ppa);
|
||||
band = ftl_band_from_addr(dev, prev_addr);
|
||||
pthread_spin_lock(&band->lba_map.lock);
|
||||
|
||||
valid = ftl_invalidate_addr_unlocked(dev, prev_ppa);
|
||||
valid = ftl_invalidate_addr_unlocked(dev, prev_addr);
|
||||
|
||||
/* If the address has been invalidated already, we don't want to update */
|
||||
/* the L2P for weak writes, as it means the write is no longer valid. */
|
||||
if (!ftl_rwb_entry_weak(entry) || valid) {
|
||||
ftl_l2p_set(dev, entry->lba, ppa);
|
||||
ftl_l2p_set(dev, entry->lba, addr);
|
||||
}
|
||||
|
||||
pthread_spin_unlock(&band->lba_map.lock);
|
||||
}
|
||||
|
||||
static struct ftl_io *
|
||||
ftl_io_init_child_write(struct ftl_io *parent, struct ftl_ppa ppa,
|
||||
ftl_io_init_child_write(struct ftl_io *parent, struct ftl_addr addr,
|
||||
void *data, void *md, ftl_io_fn cb)
|
||||
{
|
||||
struct ftl_io *io;
|
||||
@ -1468,7 +1470,7 @@ ftl_io_init_child_write(struct ftl_io *parent, struct ftl_ppa ppa,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
io->ppa = ppa;
|
||||
io->addr = addr;
|
||||
|
||||
return io;
|
||||
}
|
||||
@ -1479,7 +1481,7 @@ ftl_io_child_write_cb(struct ftl_io *io, void *ctx, int status)
|
||||
struct ftl_zone *zone;
|
||||
struct ftl_wptr *wptr;
|
||||
|
||||
zone = ftl_band_zone_from_ppa(io->band, io->ppa);
|
||||
zone = ftl_band_zone_from_addr(io->band, io->addr);
|
||||
wptr = ftl_wptr_from_band(io->band);
|
||||
|
||||
zone->busy = false;
|
||||
@ -1497,18 +1499,18 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
|
||||
struct spdk_ftl_dev *dev = io->dev;
|
||||
struct ftl_io *child;
|
||||
int rc;
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
|
||||
if (spdk_likely(!wptr->direct_mode)) {
|
||||
ppa = wptr->ppa;
|
||||
addr = wptr->addr;
|
||||
} else {
|
||||
assert(io->flags & FTL_IO_DIRECT_ACCESS);
|
||||
assert(io->ppa.zone_id == wptr->band->id);
|
||||
ppa = io->ppa;
|
||||
assert(io->addr.zone_id == wptr->band->id);
|
||||
addr = io->addr;
|
||||
}
|
||||
|
||||
/* Split IO to child requests and release zone immediately after child is completed */
|
||||
child = ftl_io_init_child_write(io, ppa, ftl_io_iovec_addr(io),
|
||||
child = ftl_io_init_child_write(io, addr, ftl_io_iovec_addr(io),
|
||||
ftl_io_get_md(io), ftl_io_child_write_cb);
|
||||
if (!child) {
|
||||
return -EAGAIN;
|
||||
@ -1517,14 +1519,14 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
|
||||
wptr->num_outstanding++;
|
||||
rc = spdk_nvme_ns_cmd_write_with_md(dev->ns, ftl_get_write_qpair(dev),
|
||||
ftl_io_iovec_addr(child), child->md,
|
||||
ftl_ppa_addr_pack(dev, ppa),
|
||||
ftl_addr_addr_pack(dev, addr),
|
||||
lbk_cnt, ftl_io_cmpl_cb, child, 0, 0, 0);
|
||||
if (rc) {
|
||||
wptr->num_outstanding--;
|
||||
ftl_io_fail(child, rc);
|
||||
ftl_io_complete(child);
|
||||
SPDK_ERRLOG("spdk_nvme_ns_cmd_write_with_md failed with status:%d, ppa:%lu\n",
|
||||
rc, ppa.addr);
|
||||
SPDK_ERRLOG("spdk_nvme_ns_cmd_write_with_md failed with status:%d, addr:%lu\n",
|
||||
rc, addr.addr);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -1561,7 +1563,7 @@ ftl_submit_write(struct ftl_wptr *wptr, struct ftl_io *io)
|
||||
break;
|
||||
}
|
||||
|
||||
ftl_trace_submission(dev, io, wptr->ppa, dev->xfer_size);
|
||||
ftl_trace_submission(dev, io, wptr->addr, dev->xfer_size);
|
||||
ftl_wptr_advance(wptr, dev->xfer_size);
|
||||
}
|
||||
|
||||
@ -1602,7 +1604,7 @@ ftl_wptr_process_writes(struct ftl_wptr *wptr)
|
||||
struct ftl_rwb_batch *batch;
|
||||
struct ftl_rwb_entry *entry;
|
||||
struct ftl_io *io;
|
||||
struct ftl_ppa ppa, prev_ppa;
|
||||
struct ftl_addr addr, prev_addr;
|
||||
|
||||
if (spdk_unlikely(!TAILQ_EMPTY(&wptr->pending_queue))) {
|
||||
io = TAILQ_FIRST(&wptr->pending_queue);
|
||||
@ -1642,7 +1644,7 @@ ftl_wptr_process_writes(struct ftl_wptr *wptr)
|
||||
goto error;
|
||||
}
|
||||
|
||||
ppa = wptr->ppa;
|
||||
addr = wptr->addr;
|
||||
ftl_rwb_foreach(entry, batch) {
|
||||
/* Update band's relocation stats if the IO comes from reloc */
|
||||
if (entry->flags & FTL_IO_WEAK) {
|
||||
@ -1652,17 +1654,17 @@ ftl_wptr_process_writes(struct ftl_wptr *wptr)
|
||||
}
|
||||
}
|
||||
|
||||
entry->ppa = ppa;
|
||||
entry->addr = addr;
|
||||
if (entry->lba != FTL_LBA_INVALID) {
|
||||
pthread_spin_lock(&entry->lock);
|
||||
prev_ppa = ftl_l2p_get(dev, entry->lba);
|
||||
prev_addr = ftl_l2p_get(dev, entry->lba);
|
||||
|
||||
/* If the l2p was updated in the meantime, don't update band's metadata */
|
||||
if (ftl_ppa_cached(prev_ppa) && prev_ppa.cache_offset == entry->pos) {
|
||||
if (ftl_addr_cached(prev_addr) && prev_addr.cache_offset == entry->pos) {
|
||||
/* Setting entry's cache bit needs to be done after metadata */
|
||||
/* within the band is updated to make sure that writes */
|
||||
/* invalidating the entry clear the metadata as well */
|
||||
ftl_band_set_addr(wptr->band, entry->lba, entry->ppa);
|
||||
ftl_band_set_addr(wptr->band, entry->lba, entry->addr);
|
||||
ftl_rwb_entry_set_valid(entry);
|
||||
}
|
||||
pthread_spin_unlock(&entry->lock);
|
||||
@ -1671,11 +1673,11 @@ ftl_wptr_process_writes(struct ftl_wptr *wptr)
|
||||
ftl_trace_rwb_pop(dev, entry);
|
||||
ftl_update_rwb_stats(dev, entry);
|
||||
|
||||
ppa = ftl_band_next_ppa(wptr->band, ppa, 1);
|
||||
addr = ftl_band_next_addr(wptr->band, addr, 1);
|
||||
}
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write ppa:%lx, %lx\n", wptr->ppa.addr,
|
||||
ftl_ppa_addr_pack(dev, wptr->ppa));
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write addr:%lx, %lx\n", wptr->addr.addr,
|
||||
ftl_addr_addr_pack(dev, wptr->addr));
|
||||
|
||||
if (ftl_submit_write(wptr, io)) {
|
||||
/* TODO: we need some recovery here */
|
||||
@ -1722,8 +1724,8 @@ ftl_rwb_entry_fill(struct ftl_rwb_entry *entry, struct ftl_io *io)
|
||||
memcpy(entry->data, ftl_io_iovec_addr(io), FTL_BLOCK_SIZE);
|
||||
|
||||
if (ftl_rwb_entry_weak(entry)) {
|
||||
entry->band = ftl_band_from_ppa(io->dev, io->ppa);
|
||||
entry->ppa = ftl_band_next_ppa(entry->band, io->ppa, io->pos);
|
||||
entry->band = ftl_band_from_addr(io->dev, io->addr);
|
||||
entry->addr = ftl_band_next_addr(entry->band, io->addr, io->pos);
|
||||
entry->band->num_reloc_blocks++;
|
||||
}
|
||||
|
||||
@ -1740,7 +1742,7 @@ ftl_rwb_fill(struct ftl_io *io)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = io->dev;
|
||||
struct ftl_rwb_entry *entry;
|
||||
struct ftl_ppa ppa = { .cached = 1 };
|
||||
struct ftl_addr addr = { .cached = 1 };
|
||||
int flags = ftl_rwb_flags_from_io(io);
|
||||
|
||||
while (io->pos < io->lbk_cnt) {
|
||||
@ -1756,10 +1758,10 @@ ftl_rwb_fill(struct ftl_io *io)
|
||||
|
||||
ftl_rwb_entry_fill(entry, io);
|
||||
|
||||
ppa.cache_offset = entry->pos;
|
||||
addr.cache_offset = entry->pos;
|
||||
|
||||
ftl_trace_rwb_fill(dev, io);
|
||||
ftl_update_l2p(dev, entry, ppa);
|
||||
ftl_update_l2p(dev, entry, addr);
|
||||
ftl_io_advance(io, 1);
|
||||
|
||||
/* Needs to be done after L2P is updated to avoid race with */
|
||||
@ -2139,19 +2141,19 @@ ftl_process_anm_event(struct ftl_anm_event *event)
|
||||
return;
|
||||
}
|
||||
|
||||
band = ftl_band_from_ppa(dev, event->ppa);
|
||||
lbkoff = ftl_band_lbkoff_from_ppa(band, event->ppa);
|
||||
band = ftl_band_from_addr(dev, event->addr);
|
||||
lbkoff = ftl_band_lbkoff_from_addr(band, event->addr);
|
||||
|
||||
ftl_reloc_add(dev->reloc, band, lbkoff, event->num_lbks, 0, false);
|
||||
ftl_anm_event_complete(event);
|
||||
}
|
||||
|
||||
bool
|
||||
ftl_ppa_is_written(struct ftl_band *band, struct ftl_ppa ppa)
|
||||
ftl_addr_is_written(struct ftl_band *band, struct ftl_addr addr)
|
||||
{
|
||||
struct ftl_zone *zone = ftl_band_zone_from_ppa(band, ppa);
|
||||
struct ftl_zone *zone = ftl_band_zone_from_addr(band, addr);
|
||||
|
||||
return ppa.offset < zone->write_offset;
|
||||
return addr.offset < zone->write_offset;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include "spdk/ftl.h"
|
||||
#include "spdk/bdev.h"
|
||||
|
||||
#include "ftl_ppa.h"
|
||||
#include "ftl_addr.h"
|
||||
#include "ftl_io.h"
|
||||
#include "ftl_trace.h"
|
||||
|
||||
@ -78,7 +78,7 @@ struct ftl_stats {
|
||||
struct ftl_punit {
|
||||
struct spdk_ftl_dev *dev;
|
||||
|
||||
struct ftl_ppa start_ppa;
|
||||
struct ftl_addr start_addr;
|
||||
};
|
||||
|
||||
struct ftl_thread {
|
||||
@ -214,8 +214,8 @@ struct spdk_ftl_dev {
|
||||
|
||||
/* PPA format */
|
||||
struct ftl_ppa_fmt ppaf;
|
||||
/* PPA address size */
|
||||
size_t ppa_len;
|
||||
/* Address size */
|
||||
size_t addr_len;
|
||||
/* Device's geometry */
|
||||
struct spdk_ocssd_geometry_data geo;
|
||||
|
||||
@ -277,7 +277,7 @@ void ftl_io_write(struct ftl_io *io);
|
||||
int ftl_io_erase(struct ftl_io *io);
|
||||
int ftl_flush_rwb(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg);
|
||||
int ftl_current_limit(const struct spdk_ftl_dev *dev);
|
||||
int ftl_invalidate_addr(struct spdk_ftl_dev *dev, struct ftl_ppa ppa);
|
||||
int ftl_invalidate_addr(struct spdk_ftl_dev *dev, struct ftl_addr addr);
|
||||
int ftl_task_core(void *ctx);
|
||||
int ftl_task_read(void *ctx);
|
||||
void ftl_process_anm_event(struct ftl_anm_event *event);
|
||||
@ -290,10 +290,10 @@ int ftl_restore_md(struct spdk_ftl_dev *dev, ftl_restore_fn cb);
|
||||
int ftl_restore_device(struct ftl_restore *restore, ftl_restore_fn cb);
|
||||
void ftl_restore_nv_cache(struct ftl_restore *restore, ftl_restore_fn cb);
|
||||
int ftl_band_set_direct_access(struct ftl_band *band, bool access);
|
||||
int ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
|
||||
int ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_addr addr,
|
||||
struct spdk_ocssd_chunk_information_entry *info,
|
||||
unsigned int num_entries);
|
||||
bool ftl_ppa_is_written(struct ftl_band *band, struct ftl_ppa ppa);
|
||||
bool ftl_addr_is_written(struct ftl_band *band, struct ftl_addr addr);
|
||||
int ftl_flush_active_bands(struct spdk_ftl_dev *dev, spdk_ftl_fn cb_fn, void *cb_arg);
|
||||
int ftl_nv_cache_write_header(struct ftl_nv_cache *nv_cache, bool shutdown,
|
||||
spdk_bdev_io_completion_cb cb_fn, void *cb_arg);
|
||||
@ -303,11 +303,11 @@ int ftl_nv_cache_scrub(struct ftl_nv_cache *nv_cache, spdk_bdev_io_completion_cb
|
||||
struct spdk_io_channel *
|
||||
ftl_get_io_channel(const struct spdk_ftl_dev *dev);
|
||||
|
||||
#define ftl_to_ppa(address) \
|
||||
(struct ftl_ppa) { .addr = (uint64_t)(address) }
|
||||
#define ftl_to_addr(address) \
|
||||
(struct ftl_addr) { .addr = (uint64_t)(address) }
|
||||
|
||||
#define ftl_to_ppa_packed(address) \
|
||||
(struct ftl_ppa) { .pack.addr = (uint32_t)(address) }
|
||||
#define ftl_to_addr_packed(address) \
|
||||
(struct ftl_addr) { .pack.addr = (uint32_t)(address) }
|
||||
|
||||
static inline struct spdk_thread *
|
||||
ftl_get_core_thread(const struct spdk_ftl_dev *dev)
|
||||
@ -334,32 +334,32 @@ ftl_get_read_qpair(const struct spdk_ftl_dev *dev)
|
||||
}
|
||||
|
||||
static inline int
|
||||
ftl_ppa_packed(const struct spdk_ftl_dev *dev)
|
||||
ftl_addr_packed(const struct spdk_ftl_dev *dev)
|
||||
{
|
||||
return dev->ppa_len < 32;
|
||||
return dev->addr_len < 32;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ftl_ppa_invalid(struct ftl_ppa ppa)
|
||||
ftl_addr_invalid(struct ftl_addr addr)
|
||||
{
|
||||
return ppa.addr == ftl_to_ppa(FTL_PPA_INVALID).addr;
|
||||
return addr.addr == ftl_to_addr(FTL_ADDR_INVALID).addr;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ftl_ppa_cached(struct ftl_ppa ppa)
|
||||
ftl_addr_cached(struct ftl_addr addr)
|
||||
{
|
||||
return !ftl_ppa_invalid(ppa) && ppa.cached;
|
||||
return !ftl_addr_invalid(addr) && addr.cached;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ftl_ppa_addr_pack(const struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
ftl_addr_addr_pack(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
uint64_t lbk, chk, pu, grp;
|
||||
|
||||
lbk = ppa.offset;
|
||||
chk = ppa.zone_id;
|
||||
pu = ppa.pu / dev->geo.num_grp;
|
||||
grp = ppa.pu % dev->geo.num_grp;
|
||||
lbk = addr.offset;
|
||||
chk = addr.zone_id;
|
||||
pu = addr.pu / dev->geo.num_grp;
|
||||
grp = addr.pu % dev->geo.num_grp;
|
||||
|
||||
return (lbk << dev->ppaf.lbk_offset) |
|
||||
(chk << dev->ppaf.chk_offset) |
|
||||
@ -367,65 +367,65 @@ ftl_ppa_addr_pack(const struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
(grp << dev->ppaf.grp_offset);
|
||||
}
|
||||
|
||||
static inline struct ftl_ppa
|
||||
ftl_ppa_addr_unpack(const struct spdk_ftl_dev *dev, uint64_t ppa)
|
||||
static inline struct ftl_addr
|
||||
ftl_addr_addr_unpack(const struct spdk_ftl_dev *dev, uint64_t addr)
|
||||
{
|
||||
struct ftl_ppa res = {};
|
||||
struct ftl_addr res = {};
|
||||
unsigned int pu, grp;
|
||||
|
||||
res.offset = (ppa >> dev->ppaf.lbk_offset) & dev->ppaf.lbk_mask;
|
||||
res.zone_id = (ppa >> dev->ppaf.chk_offset) & dev->ppaf.chk_mask;
|
||||
pu = (ppa >> dev->ppaf.pu_offset) & dev->ppaf.pu_mask;
|
||||
grp = (ppa >> dev->ppaf.grp_offset) & dev->ppaf.grp_mask;
|
||||
res.offset = (addr >> dev->ppaf.lbk_offset) & dev->ppaf.lbk_mask;
|
||||
res.zone_id = (addr >> dev->ppaf.chk_offset) & dev->ppaf.chk_mask;
|
||||
pu = (addr >> dev->ppaf.pu_offset) & dev->ppaf.pu_mask;
|
||||
grp = (addr >> dev->ppaf.grp_offset) & dev->ppaf.grp_mask;
|
||||
res.pu = grp * dev->geo.num_pu + pu;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline struct ftl_ppa
|
||||
ftl_ppa_to_packed(const struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
static inline struct ftl_addr
|
||||
ftl_addr_to_packed(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
struct ftl_ppa p = {};
|
||||
struct ftl_addr p = {};
|
||||
|
||||
if (ftl_ppa_invalid(ppa)) {
|
||||
p = ftl_to_ppa_packed(FTL_PPA_INVALID);
|
||||
} else if (ftl_ppa_cached(ppa)) {
|
||||
if (ftl_addr_invalid(addr)) {
|
||||
p = ftl_to_addr_packed(FTL_ADDR_INVALID);
|
||||
} else if (ftl_addr_cached(addr)) {
|
||||
p.pack.cached = 1;
|
||||
p.pack.cache_offset = (uint32_t) ppa.cache_offset;
|
||||
p.pack.cache_offset = (uint32_t) addr.cache_offset;
|
||||
} else {
|
||||
p.pack.addr = (uint32_t) ftl_ppa_addr_pack(dev, ppa);
|
||||
p.pack.addr = (uint32_t) ftl_addr_addr_pack(dev, addr);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline struct ftl_ppa
|
||||
ftl_ppa_from_packed(const struct spdk_ftl_dev *dev, struct ftl_ppa p)
|
||||
static inline struct ftl_addr
|
||||
ftl_addr_from_packed(const struct spdk_ftl_dev *dev, struct ftl_addr p)
|
||||
{
|
||||
struct ftl_ppa ppa = {};
|
||||
struct ftl_addr addr = {};
|
||||
|
||||
if (p.pack.addr == (uint32_t)FTL_PPA_INVALID) {
|
||||
ppa = ftl_to_ppa(FTL_PPA_INVALID);
|
||||
if (p.pack.addr == (uint32_t)FTL_ADDR_INVALID) {
|
||||
addr = ftl_to_addr(FTL_ADDR_INVALID);
|
||||
} else if (p.pack.cached) {
|
||||
ppa.cached = 1;
|
||||
ppa.cache_offset = p.pack.cache_offset;
|
||||
addr.cached = 1;
|
||||
addr.cache_offset = p.pack.cache_offset;
|
||||
} else {
|
||||
ppa = ftl_ppa_addr_unpack(dev, p.pack.addr);
|
||||
addr = ftl_addr_addr_unpack(dev, p.pack.addr);
|
||||
}
|
||||
|
||||
return ppa;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
ftl_ppa_flatten_punit(const struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
ftl_addr_flatten_punit(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
return ppa.pu - dev->range.begin;
|
||||
return addr.pu - dev->range.begin;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ftl_ppa_in_range(const struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
ftl_addr_in_range(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
if (ppa.pu >= dev->range.begin && ppa.pu <= dev->range.end) {
|
||||
if (addr.pu >= dev->range.begin && addr.pu <= dev->range.end) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -450,31 +450,31 @@ ftl_ppa_in_range(const struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
|
||||
#define _ftl_l2p_get64(l2p, off) \
|
||||
_ftl_l2p_get(l2p, off, 64)
|
||||
|
||||
#define ftl_ppa_cmp(p1, p2) \
|
||||
#define ftl_addr_cmp(p1, p2) \
|
||||
((p1).addr == (p2).addr)
|
||||
|
||||
static inline void
|
||||
ftl_l2p_set(struct spdk_ftl_dev *dev, uint64_t lba, struct ftl_ppa ppa)
|
||||
ftl_l2p_set(struct spdk_ftl_dev *dev, uint64_t lba, struct ftl_addr addr)
|
||||
{
|
||||
assert(dev->num_lbas > lba);
|
||||
|
||||
if (ftl_ppa_packed(dev)) {
|
||||
_ftl_l2p_set32(dev->l2p, lba, ftl_ppa_to_packed(dev, ppa).addr);
|
||||
if (ftl_addr_packed(dev)) {
|
||||
_ftl_l2p_set32(dev->l2p, lba, ftl_addr_to_packed(dev, addr).addr);
|
||||
} else {
|
||||
_ftl_l2p_set64(dev->l2p, lba, ppa.addr);
|
||||
_ftl_l2p_set64(dev->l2p, lba, addr.addr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct ftl_ppa
|
||||
static inline struct ftl_addr
|
||||
ftl_l2p_get(struct spdk_ftl_dev *dev, uint64_t lba)
|
||||
{
|
||||
assert(dev->num_lbas > lba);
|
||||
|
||||
if (ftl_ppa_packed(dev)) {
|
||||
return ftl_ppa_from_packed(dev, ftl_to_ppa_packed(
|
||||
if (ftl_addr_packed(dev)) {
|
||||
return ftl_addr_from_packed(dev, ftl_to_addr_packed(
|
||||
_ftl_l2p_get32(dev->l2p, lba)));
|
||||
} else {
|
||||
return ftl_to_ppa(_ftl_l2p_get64(dev->l2p, lba));
|
||||
return ftl_to_addr(_ftl_l2p_get64(dev->l2p, lba));
|
||||
}
|
||||
}
|
||||
static inline size_t
|
||||
|
@ -55,7 +55,7 @@ ftl_band_validate_md(struct ftl_band *band)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
struct ftl_lba_map *lba_map = &band->lba_map;
|
||||
struct ftl_ppa ppa_md, ppa_l2p;
|
||||
struct ftl_addr addr_md, addr_l2p;
|
||||
size_t i, size, seg_off;
|
||||
bool valid = true;
|
||||
|
||||
@ -72,14 +72,14 @@ ftl_band_validate_md(struct ftl_band *band)
|
||||
continue;
|
||||
}
|
||||
|
||||
ppa_md = ftl_band_ppa_from_lbkoff(band, i);
|
||||
ppa_l2p = ftl_l2p_get(dev, lba_map->map[i]);
|
||||
addr_md = ftl_band_addr_from_lbkoff(band, i);
|
||||
addr_l2p = ftl_l2p_get(dev, lba_map->map[i]);
|
||||
|
||||
if (ppa_l2p.cached) {
|
||||
if (addr_l2p.cached) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ppa_l2p.addr != ppa_md.addr) {
|
||||
if (addr_l2p.addr != addr_md.addr) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
#ifndef FTL_DEBUG_H
|
||||
#define FTL_DEBUG_H
|
||||
|
||||
#include "ftl_ppa.h"
|
||||
#include "ftl_addr.h"
|
||||
#include "ftl_band.h"
|
||||
#include "ftl_core.h"
|
||||
#include "ftl_rwb.h"
|
||||
@ -51,10 +51,10 @@
|
||||
#endif
|
||||
|
||||
static inline const char *
|
||||
ftl_ppa2str(struct ftl_ppa ppa, char *buf, size_t size)
|
||||
ftl_addr2str(struct ftl_addr addr, char *buf, size_t size)
|
||||
{
|
||||
snprintf(buf, size, "(pu: %u, chk: %u, lbk: %u)",
|
||||
ppa.pu, ppa.zone_id, ppa.offset);
|
||||
addr.pu, addr.zone_id, addr.offset);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -203,16 +203,16 @@ out:
|
||||
}
|
||||
|
||||
int
|
||||
ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
|
||||
ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_addr addr,
|
||||
struct spdk_ocssd_chunk_information_entry *info,
|
||||
unsigned int num_entries)
|
||||
{
|
||||
volatile struct ftl_admin_cmpl cmpl = {};
|
||||
uint32_t nsid = spdk_nvme_ns_get_id(dev->ns);
|
||||
unsigned int grp = ppa.pu % dev->geo.num_grp;
|
||||
unsigned int punit = ppa.pu / dev->geo.num_grp;
|
||||
unsigned int grp = addr.pu % dev->geo.num_grp;
|
||||
unsigned int punit = addr.pu / dev->geo.num_grp;
|
||||
uint64_t offset = (grp * dev->geo.num_pu + punit) *
|
||||
dev->geo.num_chk + ppa.zone_id;
|
||||
dev->geo.num_chk + addr.zone_id;
|
||||
int rc;
|
||||
|
||||
rc = spdk_nvme_ctrlr_cmd_get_log_page(dev->ctrlr, SPDK_OCSSD_LOG_CHUNK_INFO, nsid,
|
||||
@ -243,17 +243,17 @@ ftl_retrieve_punit_chunk_info(struct spdk_ftl_dev *dev, const struct ftl_punit *
|
||||
{
|
||||
uint32_t i = 0;
|
||||
unsigned int num_entries = FTL_BLOCK_SIZE / sizeof(*info);
|
||||
struct ftl_ppa chunk_ppa = punit->start_ppa;
|
||||
char ppa_buf[128];
|
||||
struct ftl_addr chunk_addr = punit->start_addr;
|
||||
char addr_buf[128];
|
||||
|
||||
for (i = 0; i < dev->geo.num_chk; i += num_entries, chunk_ppa.zone_id += num_entries) {
|
||||
for (i = 0; i < dev->geo.num_chk; i += num_entries, chunk_addr.zone_id += num_entries) {
|
||||
if (num_entries > dev->geo.num_chk - i) {
|
||||
num_entries = dev->geo.num_chk - i;
|
||||
}
|
||||
|
||||
if (ftl_retrieve_chunk_info(dev, chunk_ppa, &info[i], num_entries)) {
|
||||
SPDK_ERRLOG("Failed to retrieve chunk information @ppa: %s\n",
|
||||
ftl_ppa2str(chunk_ppa, ppa_buf, sizeof(ppa_buf)));
|
||||
if (ftl_retrieve_chunk_info(dev, chunk_addr, &info[i], num_entries)) {
|
||||
SPDK_ERRLOG("Failed to retrieve chunk information @addr: %s\n",
|
||||
ftl_addr2str(chunk_addr, addr_buf, sizeof(addr_buf)));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -364,9 +364,9 @@ ftl_dev_init_bands(struct spdk_ftl_dev *dev)
|
||||
|
||||
rc = ftl_retrieve_punit_chunk_info(dev, punit, info);
|
||||
if (rc) {
|
||||
SPDK_ERRLOG("Failed to retrieve bbt for @ppa: %s [%lu]\n",
|
||||
ftl_ppa2str(punit->start_ppa, buf, sizeof(buf)),
|
||||
ftl_ppa_addr_pack(dev, punit->start_ppa));
|
||||
SPDK_ERRLOG("Failed to retrieve bbt for @addr: %s [%lu]\n",
|
||||
ftl_addr2str(punit->start_addr, buf, sizeof(buf)),
|
||||
ftl_addr_addr_pack(dev, punit->start_addr));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -376,8 +376,8 @@ ftl_dev_init_bands(struct spdk_ftl_dev *dev)
|
||||
zone->pos = i;
|
||||
zone->state = ftl_get_zone_state(&info[j]);
|
||||
zone->punit = punit;
|
||||
zone->start_ppa = punit->start_ppa;
|
||||
zone->start_ppa.zone_id = band->id;
|
||||
zone->start_addr = punit->start_addr;
|
||||
zone->start_addr.zone_id = band->id;
|
||||
zone->write_offset = ftl_dev_lbks_in_zone(dev);
|
||||
|
||||
if (zone->state != SPDK_BDEV_ZONE_STATE_OFFLINE) {
|
||||
@ -389,7 +389,7 @@ ftl_dev_init_bands(struct spdk_ftl_dev *dev)
|
||||
|
||||
for (i = 0; i < ftl_dev_num_bands(dev); ++i) {
|
||||
band = &dev->bands[i];
|
||||
band->tail_md_ppa = ftl_band_tail_md_ppa(band);
|
||||
band->tail_md_addr = ftl_band_tail_md_addr(band);
|
||||
}
|
||||
|
||||
ftl_remove_empty_bands(dev);
|
||||
@ -412,8 +412,8 @@ ftl_dev_init_punits(struct spdk_ftl_dev *dev)
|
||||
dev->punits[i].dev = dev;
|
||||
punit = dev->range.begin + i;
|
||||
|
||||
dev->punits[i].start_ppa.addr = 0;
|
||||
dev->punits[i].start_ppa.pu = punit;
|
||||
dev->punits[i].start_addr.addr = 0;
|
||||
dev->punits[i].start_addr.pu = punit;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -443,7 +443,7 @@ ftl_dev_retrieve_geo(struct spdk_ftl_dev *dev)
|
||||
}
|
||||
|
||||
/* TODO: add sanity checks for the geo */
|
||||
dev->ppa_len = dev->geo.lbaf.grp_len +
|
||||
dev->addr_len = dev->geo.lbaf.grp_len +
|
||||
dev->geo.lbaf.pu_len +
|
||||
dev->geo.lbaf.chk_len +
|
||||
dev->geo.lbaf.lbk_len;
|
||||
@ -804,7 +804,7 @@ ftl_dev_l2p_alloc(struct spdk_ftl_dev *dev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr_size = dev->ppa_len >= 32 ? 8 : 4;
|
||||
addr_size = dev->addr_len >= 32 ? 8 : 4;
|
||||
dev->l2p = malloc(dev->num_lbas * addr_size);
|
||||
if (!dev->l2p) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_INIT, "Failed to allocate l2p table\n");
|
||||
@ -812,7 +812,7 @@ ftl_dev_l2p_alloc(struct spdk_ftl_dev *dev)
|
||||
}
|
||||
|
||||
for (i = 0; i < dev->num_lbas; ++i) {
|
||||
ftl_l2p_set(dev, i, ftl_to_ppa(FTL_PPA_INVALID));
|
||||
ftl_l2p_set(dev, i, ftl_to_addr(FTL_ADDR_INVALID));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -263,7 +263,7 @@ ftl_io_init(struct ftl_io *io, struct spdk_ftl_dev *dev,
|
||||
io->type = type;
|
||||
io->dev = dev;
|
||||
io->lba.single = FTL_LBA_INVALID;
|
||||
io->ppa.addr = FTL_PPA_INVALID;
|
||||
io->addr.addr = FTL_ADDR_INVALID;
|
||||
io->cb_fn = fn;
|
||||
io->cb_ctx = ctx;
|
||||
io->trace = ftl_trace_alloc_id(dev);
|
||||
@ -356,7 +356,7 @@ ftl_io_erase_init(struct ftl_band *band, size_t lbk_cnt, ftl_io_fn cb)
|
||||
.rwb_batch = NULL,
|
||||
.band = band,
|
||||
.size = sizeof(struct ftl_io),
|
||||
.flags = FTL_IO_PPA_MODE,
|
||||
.flags = FTL_IO_PHYSICAL_MODE,
|
||||
.type = FTL_IO_ERASE,
|
||||
.lbk_cnt = 1,
|
||||
.cb_fn = cb,
|
||||
@ -489,7 +489,7 @@ ftl_io_alloc_child(struct ftl_io *parent)
|
||||
void
|
||||
ftl_io_process_error(struct ftl_io *io, const struct spdk_nvme_cpl *status)
|
||||
{
|
||||
char ppa_buf[128];
|
||||
char addr_buf[128];
|
||||
|
||||
/* TODO: add error handling for specifc cases */
|
||||
if (status->status.sct == SPDK_NVME_SCT_MEDIA_ERROR &&
|
||||
@ -497,8 +497,8 @@ ftl_io_process_error(struct ftl_io *io, const struct spdk_nvme_cpl *status)
|
||||
return;
|
||||
}
|
||||
|
||||
SPDK_ERRLOG("Status code type 0x%x, status code 0x%x for IO type %u @ppa: %s, lba 0x%lx, cnt %lu\n",
|
||||
status->status.sct, status->status.sc, io->type, ftl_ppa2str(io->ppa, ppa_buf, sizeof(ppa_buf)),
|
||||
SPDK_ERRLOG("Status code type 0x%x, status code 0x%x for IO type %u @addr: %s, lba 0x%lx, cnt %lu\n",
|
||||
status->status.sct, status->status.sc, io->type, ftl_addr2str(io->addr, addr_buf, sizeof(addr_buf)),
|
||||
ftl_io_get_lba(io, 0), io->lbk_cnt);
|
||||
|
||||
io->status = -EIO;
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "spdk/nvme.h"
|
||||
#include "spdk/ftl.h"
|
||||
|
||||
#include "ftl_ppa.h"
|
||||
#include "ftl_addr.h"
|
||||
#include "ftl_trace.h"
|
||||
|
||||
struct spdk_ftl_dev;
|
||||
@ -62,15 +62,15 @@ enum ftl_io_flags {
|
||||
FTL_IO_PAD = (1 << 3),
|
||||
/* The IO operates on metadata */
|
||||
FTL_IO_MD = (1 << 4),
|
||||
/* Using PPA instead of LBA */
|
||||
FTL_IO_PPA_MODE = (1 << 5),
|
||||
/* Using physical instead of logical address */
|
||||
FTL_IO_PHYSICAL_MODE = (1 << 5),
|
||||
/* Indicates that IO contains noncontiguous LBAs */
|
||||
FTL_IO_VECTOR_LBA = (1 << 6),
|
||||
/* Indicates that IO is being retried */
|
||||
FTL_IO_RETRY = (1 << 7),
|
||||
/* The IO is directed to non-volatile cache */
|
||||
FTL_IO_CACHE = (1 << 8),
|
||||
/* Indicates that PPA should be taken from IO struct, */
|
||||
/* Indicates that physical address should be taken from IO struct, */
|
||||
/* not assigned by wptr, only works if wptr is also in direct mode */
|
||||
FTL_IO_DIRECT_ACCESS = (1 << 9),
|
||||
/* Bypass the non-volatile cache */
|
||||
@ -150,8 +150,8 @@ struct ftl_io {
|
||||
uint64_t single;
|
||||
} lba;
|
||||
|
||||
/* First PPA */
|
||||
struct ftl_ppa ppa;
|
||||
/* First block address */
|
||||
struct ftl_addr addr;
|
||||
|
||||
/* Number of processed lbks */
|
||||
size_t pos;
|
||||
@ -235,15 +235,15 @@ struct ftl_md_io {
|
||||
};
|
||||
|
||||
static inline bool
|
||||
ftl_io_mode_ppa(const struct ftl_io *io)
|
||||
ftl_io_mode_physical(const struct ftl_io *io)
|
||||
{
|
||||
return io->flags & FTL_IO_PPA_MODE;
|
||||
return io->flags & FTL_IO_PHYSICAL_MODE;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ftl_io_mode_lba(const struct ftl_io *io)
|
||||
ftl_io_mode_logical(const struct ftl_io *io)
|
||||
{
|
||||
return !ftl_io_mode_ppa(io);
|
||||
return !ftl_io_mode_physical(io);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -64,8 +64,8 @@ enum ftl_band_reloc_state {
|
||||
struct ftl_reloc_move {
|
||||
struct ftl_band_reloc *breloc;
|
||||
|
||||
/* Start ppa */
|
||||
struct ftl_ppa ppa;
|
||||
/* Start addr */
|
||||
struct ftl_addr addr;
|
||||
|
||||
/* Number of logical blocks */
|
||||
size_t lbk_cnt;
|
||||
@ -205,7 +205,7 @@ ftl_reloc_read_lba_map(struct ftl_band_reloc *breloc, struct ftl_reloc_move *mov
|
||||
struct ftl_band *band = breloc->band;
|
||||
|
||||
breloc->num_outstanding++;
|
||||
return ftl_band_read_lba_map(band, ftl_band_lbkoff_from_ppa(band, move->ppa),
|
||||
return ftl_band_read_lba_map(band, ftl_band_lbkoff_from_addr(band, move->addr),
|
||||
move->lbk_cnt, ftl_reloc_read_lba_map_cb, move);
|
||||
}
|
||||
|
||||
@ -252,7 +252,7 @@ static void
|
||||
ftl_reloc_write_cb(struct ftl_io *io, void *arg, int status)
|
||||
{
|
||||
struct ftl_reloc_move *move = arg;
|
||||
struct ftl_ppa ppa = move->ppa;
|
||||
struct ftl_addr addr = move->addr;
|
||||
struct ftl_band_reloc *breloc = move->breloc;
|
||||
size_t i;
|
||||
|
||||
@ -265,8 +265,8 @@ ftl_reloc_write_cb(struct ftl_io *io, void *arg, int status)
|
||||
}
|
||||
|
||||
for (i = 0; i < move->lbk_cnt; ++i) {
|
||||
ppa.offset = move->ppa.offset + i;
|
||||
size_t lbkoff = ftl_band_lbkoff_from_ppa(breloc->band, ppa);
|
||||
addr.offset = move->addr.offset + i;
|
||||
size_t lbkoff = ftl_band_lbkoff_from_addr(breloc->band, addr);
|
||||
ftl_reloc_clr_lbk(breloc, lbkoff);
|
||||
}
|
||||
|
||||
@ -322,9 +322,9 @@ ftl_reloc_iter_next_zone(struct ftl_band_reloc *breloc)
|
||||
static int
|
||||
ftl_reloc_lbk_valid(struct ftl_band_reloc *breloc, size_t lbkoff)
|
||||
{
|
||||
struct ftl_ppa ppa = ftl_band_ppa_from_lbkoff(breloc->band, lbkoff);
|
||||
struct ftl_addr addr = ftl_band_addr_from_lbkoff(breloc->band, lbkoff);
|
||||
|
||||
return ftl_ppa_is_written(breloc->band, ppa) &&
|
||||
return ftl_addr_is_written(breloc->band, addr) &&
|
||||
spdk_bit_array_get(breloc->reloc_map, lbkoff) &&
|
||||
ftl_band_lbkoff_valid(breloc->band, lbkoff);
|
||||
}
|
||||
@ -382,7 +382,7 @@ ftl_reloc_iter_done(struct ftl_band_reloc *breloc)
|
||||
|
||||
static size_t
|
||||
ftl_reloc_find_valid_lbks(struct ftl_band_reloc *breloc,
|
||||
size_t num_lbk, struct ftl_ppa *ppa)
|
||||
size_t num_lbk, struct ftl_addr *addr)
|
||||
{
|
||||
size_t lbkoff, lbk_cnt = 0;
|
||||
|
||||
@ -390,7 +390,7 @@ ftl_reloc_find_valid_lbks(struct ftl_band_reloc *breloc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
*ppa = ftl_band_ppa_from_lbkoff(breloc->band, lbkoff);
|
||||
*addr = ftl_band_addr_from_lbkoff(breloc->band, lbkoff);
|
||||
|
||||
for (lbk_cnt = 1; lbk_cnt < num_lbk; lbk_cnt++) {
|
||||
if (!ftl_reloc_iter_next(breloc, &lbkoff)) {
|
||||
@ -402,13 +402,13 @@ ftl_reloc_find_valid_lbks(struct ftl_band_reloc *breloc,
|
||||
}
|
||||
|
||||
static size_t
|
||||
ftl_reloc_next_lbks(struct ftl_band_reloc *breloc, struct ftl_ppa *ppa)
|
||||
ftl_reloc_next_lbks(struct ftl_band_reloc *breloc, struct ftl_addr *addr)
|
||||
{
|
||||
size_t i, lbk_cnt = 0;
|
||||
struct spdk_ftl_dev *dev = breloc->parent->dev;
|
||||
|
||||
for (i = 0; i < ftl_dev_num_punits(dev); ++i) {
|
||||
lbk_cnt = ftl_reloc_find_valid_lbks(breloc, breloc->parent->xfer_size, ppa);
|
||||
lbk_cnt = ftl_reloc_find_valid_lbks(breloc, breloc->parent->xfer_size, addr);
|
||||
ftl_reloc_iter_next_zone(breloc);
|
||||
|
||||
if (lbk_cnt || ftl_reloc_iter_done(breloc)) {
|
||||
@ -424,13 +424,13 @@ ftl_reloc_io_init(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move,
|
||||
ftl_io_fn fn, enum ftl_io_type io_type, int flags)
|
||||
{
|
||||
size_t lbkoff, i;
|
||||
struct ftl_ppa ppa = move->ppa;
|
||||
struct ftl_addr addr = move->addr;
|
||||
struct ftl_io *io = NULL;
|
||||
struct ftl_io_init_opts opts = {
|
||||
.dev = breloc->parent->dev,
|
||||
.band = breloc->band,
|
||||
.size = sizeof(*io),
|
||||
.flags = flags | FTL_IO_INTERNAL | FTL_IO_PPA_MODE,
|
||||
.flags = flags | FTL_IO_INTERNAL | FTL_IO_PHYSICAL_MODE,
|
||||
.type = io_type,
|
||||
.lbk_cnt = move->lbk_cnt,
|
||||
.data = move->data,
|
||||
@ -443,11 +443,11 @@ ftl_reloc_io_init(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move,
|
||||
}
|
||||
|
||||
io->cb_ctx = move;
|
||||
io->ppa = move->ppa;
|
||||
io->addr = move->addr;
|
||||
|
||||
if (flags & FTL_IO_VECTOR_LBA) {
|
||||
for (i = 0; i < io->lbk_cnt; ++i, ++ppa.offset) {
|
||||
lbkoff = ftl_band_lbkoff_from_ppa(breloc->band, ppa);
|
||||
for (i = 0; i < io->lbk_cnt; ++i, ++addr.offset) {
|
||||
lbkoff = ftl_band_lbkoff_from_addr(breloc->band, addr);
|
||||
|
||||
if (!ftl_band_lbkoff_valid(breloc->band, lbkoff)) {
|
||||
io->lba.vector[i] = FTL_LBA_INVALID;
|
||||
@ -485,11 +485,11 @@ ftl_reloc_write(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move)
|
||||
static int
|
||||
ftl_reloc_read(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move)
|
||||
{
|
||||
struct ftl_ppa ppa = {};
|
||||
struct ftl_addr addr = {};
|
||||
|
||||
move->lbk_cnt = ftl_reloc_next_lbks(breloc, &ppa);
|
||||
move->lbk_cnt = ftl_reloc_next_lbks(breloc, &addr);
|
||||
move->breloc = breloc;
|
||||
move->ppa = ppa;
|
||||
move->addr = addr;
|
||||
|
||||
if (!move->lbk_cnt) {
|
||||
return 0;
|
||||
|
@ -383,7 +383,7 @@ static int
|
||||
ftl_restore_l2p(struct ftl_band *band)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
uint64_t lba;
|
||||
size_t i;
|
||||
|
||||
@ -397,15 +397,15 @@ ftl_restore_l2p(struct ftl_band *band)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ppa = ftl_l2p_get(dev, lba);
|
||||
if (!ftl_ppa_invalid(ppa)) {
|
||||
ftl_invalidate_addr(dev, ppa);
|
||||
addr = ftl_l2p_get(dev, lba);
|
||||
if (!ftl_addr_invalid(addr)) {
|
||||
ftl_invalidate_addr(dev, addr);
|
||||
}
|
||||
|
||||
ppa = ftl_band_ppa_from_lbkoff(band, i);
|
||||
addr = ftl_band_addr_from_lbkoff(band, i);
|
||||
|
||||
ftl_band_set_addr(band, lba, ppa);
|
||||
ftl_l2p_set(dev, lba, ppa);
|
||||
ftl_band_set_addr(band, lba, addr);
|
||||
ftl_l2p_set(dev, lba, addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1115,11 +1115,11 @@ ftl_pad_zone_pad_finish(struct ftl_restore_band *rband, bool direct_access)
|
||||
|
||||
static struct ftl_io *
|
||||
ftl_restore_init_pad_io(struct ftl_restore_band *rband, void *buffer,
|
||||
struct ftl_ppa ppa)
|
||||
struct ftl_addr addr)
|
||||
{
|
||||
struct ftl_band *band = rband->band;
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
int flags = FTL_IO_PAD | FTL_IO_INTERNAL | FTL_IO_PPA_MODE | FTL_IO_MD |
|
||||
int flags = FTL_IO_PAD | FTL_IO_INTERNAL | FTL_IO_PHYSICAL_MODE | FTL_IO_MD |
|
||||
FTL_IO_DIRECT_ACCESS;
|
||||
struct ftl_io_init_opts opts = {
|
||||
.dev = dev,
|
||||
@ -1142,7 +1142,7 @@ ftl_restore_init_pad_io(struct ftl_restore_band *rband, void *buffer,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
io->ppa = ppa;
|
||||
io->addr = addr;
|
||||
rband->parent->num_ios++;
|
||||
|
||||
return io;
|
||||
@ -1164,13 +1164,13 @@ ftl_pad_zone_cb(struct ftl_io *io, void *arg, int status)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (io->ppa.offset + io->lbk_cnt == band->dev->geo.clba) {
|
||||
zone = ftl_band_zone_from_ppa(band, io->ppa);
|
||||
if (io->addr.offset + io->lbk_cnt == band->dev->geo.clba) {
|
||||
zone = ftl_band_zone_from_addr(band, io->addr);
|
||||
zone->state = SPDK_BDEV_ZONE_STATE_CLOSED;
|
||||
} else {
|
||||
struct ftl_ppa ppa = io->ppa;
|
||||
ppa.offset += io->lbk_cnt;
|
||||
new_io = ftl_restore_init_pad_io(rband, io->iov[0].iov_base, ppa);
|
||||
struct ftl_addr addr = io->addr;
|
||||
addr.offset += io->lbk_cnt;
|
||||
new_io = ftl_restore_init_pad_io(rband, io->iov[0].iov_base, addr);
|
||||
if (spdk_unlikely(!new_io)) {
|
||||
restore->pad_status = -ENOMEM;
|
||||
goto end;
|
||||
@ -1194,7 +1194,7 @@ ftl_restore_pad_band(struct ftl_restore_band *rband)
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
void *buffer = NULL;
|
||||
struct ftl_io *io;
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
size_t i;
|
||||
int rc = 0;
|
||||
|
||||
@ -1219,12 +1219,12 @@ ftl_restore_pad_band(struct ftl_restore_band *rband)
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = ftl_retrieve_chunk_info(dev, band->zone_buf[i].start_ppa, &info, 1);
|
||||
rc = ftl_retrieve_chunk_info(dev, band->zone_buf[i].start_addr, &info, 1);
|
||||
if (spdk_unlikely(rc)) {
|
||||
goto error;
|
||||
}
|
||||
ppa = band->zone_buf[i].start_ppa;
|
||||
ppa.offset = info.wp;
|
||||
addr = band->zone_buf[i].start_addr;
|
||||
addr.offset = info.wp;
|
||||
|
||||
buffer = spdk_dma_zmalloc(FTL_BLOCK_SIZE * dev->xfer_size, 0, NULL);
|
||||
if (spdk_unlikely(!buffer)) {
|
||||
@ -1232,7 +1232,7 @@ ftl_restore_pad_band(struct ftl_restore_band *rband)
|
||||
goto error;
|
||||
}
|
||||
|
||||
io = ftl_restore_init_pad_io(rband, buffer, ppa);
|
||||
io = ftl_restore_init_pad_io(rband, buffer, addr);
|
||||
if (spdk_unlikely(!io)) {
|
||||
rc = -ENOMEM;
|
||||
spdk_dma_free(buffer);
|
||||
@ -1312,7 +1312,7 @@ ftl_restore_tail_md(struct ftl_restore_band *rband)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (ftl_band_read_tail_md(band, band->tail_md_ppa, ftl_restore_tail_md_cb, rband)) {
|
||||
if (ftl_band_read_tail_md(band, band->tail_md_addr, ftl_restore_tail_md_cb, rband)) {
|
||||
SPDK_ERRLOG("Failed to send tail metadata read\n");
|
||||
ftl_restore_complete(restore, -EIO);
|
||||
return -EIO;
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "spdk/queue.h"
|
||||
|
||||
#include "ftl_io.h"
|
||||
#include "ftl_ppa.h"
|
||||
#include "ftl_addr.h"
|
||||
#include "ftl_trace.h"
|
||||
|
||||
struct ftl_rwb;
|
||||
@ -64,7 +64,7 @@ struct ftl_rwb_entry {
|
||||
uint64_t lba;
|
||||
|
||||
/* Physical address */
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
|
||||
/* Band the data is moved from (only valid when relocating data) */
|
||||
struct ftl_band *band;
|
||||
@ -84,7 +84,7 @@ struct ftl_rwb_entry {
|
||||
/* Flags */
|
||||
unsigned int flags;
|
||||
|
||||
/* Indicates whether the entry is part of cache and is assigned a PPA */
|
||||
/* Indicates whether the entry is part of cache and is assigned a physical address */
|
||||
bool valid;
|
||||
|
||||
/* Trace group id */
|
||||
|
@ -101,20 +101,20 @@ SPDK_TRACE_REGISTER_FN(ftl_trace_func, "ftl", TRACE_GROUP_FTL)
|
||||
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_sched");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_SCHEDULE(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "ppa: ");
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_submit");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_SUBMISSION(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "ppa: ");
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_read_cmpl");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_MD_READ_COMPLETION(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
|
||||
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_sched");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_SCHEDULE(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "ppa: ");
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_submit");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_SUBMISSION(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "ppa: ");
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "md_write_cmpl");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_MD_WRITE_COMPLETION(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
|
||||
@ -124,7 +124,7 @@ SPDK_TRACE_REGISTER_FN(ftl_trace_func, "ftl", TRACE_GROUP_FTL)
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_submit");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_READ_SUBMISSION(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "ppa: ");
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "read_cmpl_invld");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_READ_COMPLETION_INVALID(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
|
||||
@ -143,17 +143,17 @@ SPDK_TRACE_REGISTER_FN(ftl_trace_func, "ftl", TRACE_GROUP_FTL)
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_submit");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_SUBMISSION(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "ppa: ");
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "write_cmpl");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_WRITE_COMPLETION(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "lba: ");
|
||||
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "erase_submit");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_ERASE_SUBMISSION(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "ppa: ");
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
|
||||
snprintf(descbuf, sizeof(descbuf), "%c %s", source[i], "erase_cmpl");
|
||||
spdk_trace_register_description(descbuf, FTL_TRACE_ERASE_COMPLETION(i),
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "ppa: ");
|
||||
OWNER_FTL, OBJECT_NONE, 0, 0, "addr: ");
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ ftl_trace_rwb_pop(struct spdk_ftl_dev *dev, const struct ftl_rwb_entry *entry)
|
||||
tpoint_id = FTL_TRACE_RWB_POP(FTL_TRACE_SOURCE_USER);
|
||||
}
|
||||
|
||||
spdk_trace_record(tpoint_id, entry->trace, 0, entry->ppa.addr, entry->lba);
|
||||
spdk_trace_record(tpoint_id, entry->trace, 0, entry->addr.addr, entry->lba);
|
||||
}
|
||||
|
||||
void
|
||||
@ -302,8 +302,8 @@ ftl_trace_completion(struct spdk_ftl_dev *dev, const struct ftl_io *io,
|
||||
}
|
||||
|
||||
void
|
||||
ftl_trace_submission(struct spdk_ftl_dev *dev, const struct ftl_io *io, struct ftl_ppa ppa,
|
||||
size_t ppa_cnt)
|
||||
ftl_trace_submission(struct spdk_ftl_dev *dev, const struct ftl_io *io, struct ftl_addr addr,
|
||||
size_t addr_cnt)
|
||||
{
|
||||
uint16_t tpoint_id = 0, source;
|
||||
|
||||
@ -337,7 +337,7 @@ ftl_trace_submission(struct spdk_ftl_dev *dev, const struct ftl_io *io, struct f
|
||||
}
|
||||
}
|
||||
|
||||
spdk_trace_record(tpoint_id, io->trace, ppa_cnt, 0, ppa.addr);
|
||||
spdk_trace_record(tpoint_id, io->trace, addr_cnt, 0, addr.addr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -34,7 +34,7 @@
|
||||
#ifndef FTL_TRACE_H
|
||||
#define FTL_TRACE_H
|
||||
|
||||
#include "ftl_ppa.h"
|
||||
#include "ftl_addr.h"
|
||||
|
||||
#define FTL_TRACE_INVALID_ID ((uint64_t) -1)
|
||||
|
||||
@ -63,7 +63,7 @@ void ftl_trace_rwb_fill(struct spdk_ftl_dev *dev, const struct ftl_io *io);
|
||||
void ftl_trace_rwb_pop(struct spdk_ftl_dev *dev, const struct ftl_rwb_entry *entry);
|
||||
void ftl_trace_submission(struct spdk_ftl_dev *dev,
|
||||
const struct ftl_io *io,
|
||||
struct ftl_ppa ppa, size_t ppa_cnt);
|
||||
struct ftl_addr addr, size_t addr_cnt);
|
||||
void ftl_trace_completion(struct spdk_ftl_dev *dev,
|
||||
const struct ftl_io *io,
|
||||
enum ftl_trace_completion type);
|
||||
|
@ -41,7 +41,7 @@ struct spdk_ftl_dev *test_init_ftl_dev(const struct spdk_ocssd_geometry_data *ge
|
||||
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_ppa(struct ftl_ppa ppa, 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,
|
||||
@ -73,7 +73,7 @@ test_init_ftl_dev(const struct spdk_ocssd_geometry_data *geo,
|
||||
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_ppa.pu = punit;
|
||||
dev->punits[i].start_addr.pu = punit;
|
||||
}
|
||||
|
||||
LIST_INIT(&dev->free_bands);
|
||||
@ -113,8 +113,8 @@ test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id)
|
||||
zone->pos = i;
|
||||
zone->state = SPDK_BDEV_ZONE_STATE_CLOSED;
|
||||
zone->punit = &dev->punits[i];
|
||||
zone->start_ppa = dev->punits[i].start_ppa;
|
||||
zone->start_ppa.zone_id = band->id;
|
||||
zone->start_addr = dev->punits[i].start_addr;
|
||||
zone->start_addr.zone_id = band->id;
|
||||
CIRCLEQ_INSERT_TAIL(&band->zones, zone, circleq);
|
||||
band->num_zones++;
|
||||
}
|
||||
@ -147,14 +147,14 @@ test_free_ftl_band(struct ftl_band *band)
|
||||
}
|
||||
|
||||
uint64_t
|
||||
test_offset_from_ppa(struct ftl_ppa ppa, struct ftl_band *band)
|
||||
test_offset_from_addr(struct ftl_addr addr, struct ftl_band *band)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
unsigned int punit;
|
||||
|
||||
/* TODO: ftl_ppa_flatten_punit should return uint32_t */
|
||||
punit = ftl_ppa_flatten_punit(dev, ppa);
|
||||
CU_ASSERT_EQUAL(ppa.zone_id, band->id);
|
||||
/* 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) + ppa.offset;
|
||||
return punit * ftl_dev_lbks_in_zone(dev) + addr.offset;
|
||||
}
|
||||
|
@ -78,27 +78,27 @@ cleanup_band(void)
|
||||
test_free_ftl_dev(g_dev);
|
||||
}
|
||||
|
||||
static struct ftl_ppa
|
||||
ppa_from_punit(uint64_t punit)
|
||||
static struct ftl_addr
|
||||
addr_from_punit(uint64_t punit)
|
||||
{
|
||||
struct ftl_ppa ppa = {};
|
||||
struct ftl_addr addr = {};
|
||||
|
||||
ppa.pu = punit;
|
||||
return ppa;
|
||||
addr.pu = punit;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static void
|
||||
test_band_lbkoff_from_ppa_base(void)
|
||||
test_band_lbkoff_from_addr_base(void)
|
||||
{
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
uint64_t offset, i, flat_lun = 0;
|
||||
|
||||
setup_band();
|
||||
for (i = g_range.begin; i < g_range.end; ++i) {
|
||||
ppa = ppa_from_punit(i);
|
||||
ppa.zone_id = TEST_BAND_IDX;
|
||||
addr = addr_from_punit(i);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
|
||||
offset = ftl_band_lbkoff_from_ppa(g_band, ppa);
|
||||
offset = ftl_band_lbkoff_from_addr(g_band, addr);
|
||||
CU_ASSERT_EQUAL(offset, flat_lun * ftl_dev_lbks_in_zone(g_dev));
|
||||
flat_lun++;
|
||||
}
|
||||
@ -106,21 +106,21 @@ test_band_lbkoff_from_ppa_base(void)
|
||||
}
|
||||
|
||||
static void
|
||||
test_band_lbkoff_from_ppa_lbk(void)
|
||||
test_band_lbkoff_from_addr_offset(void)
|
||||
{
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
uint64_t offset, expect, i, j;
|
||||
|
||||
setup_band();
|
||||
for (i = g_range.begin; i < g_range.end; ++i) {
|
||||
for (j = 0; j < g_geo.clba; ++j) {
|
||||
ppa = ppa_from_punit(i);
|
||||
ppa.zone_id = TEST_BAND_IDX;
|
||||
ppa.offset = j;
|
||||
addr = addr_from_punit(i);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset = j;
|
||||
|
||||
offset = ftl_band_lbkoff_from_ppa(g_band, ppa);
|
||||
offset = ftl_band_lbkoff_from_addr(g_band, addr);
|
||||
|
||||
expect = test_offset_from_ppa(ppa, g_band);
|
||||
expect = test_offset_from_addr(addr, g_band);
|
||||
CU_ASSERT_EQUAL(offset, expect);
|
||||
}
|
||||
}
|
||||
@ -128,22 +128,22 @@ test_band_lbkoff_from_ppa_lbk(void)
|
||||
}
|
||||
|
||||
static void
|
||||
test_band_ppa_from_lbkoff(void)
|
||||
test_band_addr_from_lbkoff(void)
|
||||
{
|
||||
struct ftl_ppa ppa, expect;
|
||||
struct ftl_addr addr, expect;
|
||||
uint64_t offset, i, j;
|
||||
|
||||
setup_band();
|
||||
for (i = g_range.begin; i < g_range.end; ++i) {
|
||||
for (j = 0; j < g_geo.clba; ++j) {
|
||||
expect = ppa_from_punit(i);
|
||||
expect = addr_from_punit(i);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = j;
|
||||
|
||||
offset = ftl_band_lbkoff_from_ppa(g_band, expect);
|
||||
ppa = ftl_band_ppa_from_lbkoff(g_band, offset);
|
||||
offset = ftl_band_lbkoff_from_addr(g_band, expect);
|
||||
addr = ftl_band_addr_from_lbkoff(g_band, offset);
|
||||
|
||||
CU_ASSERT_EQUAL(ppa.addr, expect.addr);
|
||||
CU_ASSERT_EQUAL(addr.addr, expect.addr);
|
||||
}
|
||||
}
|
||||
cleanup_band();
|
||||
@ -153,31 +153,31 @@ static void
|
||||
test_band_set_addr(void)
|
||||
{
|
||||
struct ftl_lba_map *lba_map;
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
uint64_t offset = 0;
|
||||
|
||||
setup_band();
|
||||
lba_map = &g_band->lba_map;
|
||||
ppa = ppa_from_punit(g_range.begin);
|
||||
ppa.zone_id = TEST_BAND_IDX;
|
||||
addr = addr_from_punit(g_range.begin);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 0);
|
||||
|
||||
offset = test_offset_from_ppa(ppa, g_band);
|
||||
offset = test_offset_from_addr(addr, g_band);
|
||||
|
||||
ftl_band_set_addr(g_band, TEST_LBA, ppa);
|
||||
ftl_band_set_addr(g_band, TEST_LBA, addr);
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 1);
|
||||
CU_ASSERT_EQUAL(lba_map->map[offset], TEST_LBA);
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset));
|
||||
|
||||
ppa.pu++;
|
||||
offset = test_offset_from_ppa(ppa, g_band);
|
||||
ftl_band_set_addr(g_band, TEST_LBA + 1, ppa);
|
||||
addr.pu++;
|
||||
offset = test_offset_from_addr(addr, g_band);
|
||||
ftl_band_set_addr(g_band, TEST_LBA + 1, addr);
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 2);
|
||||
CU_ASSERT_EQUAL(lba_map->map[offset], TEST_LBA + 1);
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset));
|
||||
ppa.pu--;
|
||||
offset = test_offset_from_ppa(ppa, g_band);
|
||||
addr.pu--;
|
||||
offset = test_offset_from_addr(addr, g_band);
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset));
|
||||
cleanup_band();
|
||||
}
|
||||
@ -186,31 +186,31 @@ static void
|
||||
test_invalidate_addr(void)
|
||||
{
|
||||
struct ftl_lba_map *lba_map;
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
uint64_t offset[2];
|
||||
|
||||
setup_band();
|
||||
lba_map = &g_band->lba_map;
|
||||
ppa = ppa_from_punit(g_range.begin);
|
||||
ppa.zone_id = TEST_BAND_IDX;
|
||||
offset[0] = test_offset_from_ppa(ppa, g_band);
|
||||
addr = addr_from_punit(g_range.begin);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
offset[0] = test_offset_from_addr(addr, g_band);
|
||||
|
||||
ftl_band_set_addr(g_band, TEST_LBA, ppa);
|
||||
ftl_band_set_addr(g_band, TEST_LBA, addr);
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 1);
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset[0]));
|
||||
ftl_invalidate_addr(g_band->dev, ppa);
|
||||
ftl_invalidate_addr(g_band->dev, addr);
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 0);
|
||||
CU_ASSERT_FALSE(spdk_bit_array_get(lba_map->vld, offset[0]));
|
||||
|
||||
offset[0] = test_offset_from_ppa(ppa, g_band);
|
||||
ftl_band_set_addr(g_band, TEST_LBA, ppa);
|
||||
ppa.pu++;
|
||||
offset[1] = test_offset_from_ppa(ppa, g_band);
|
||||
ftl_band_set_addr(g_band, TEST_LBA + 1, ppa);
|
||||
offset[0] = test_offset_from_addr(addr, g_band);
|
||||
ftl_band_set_addr(g_band, TEST_LBA, addr);
|
||||
addr.pu++;
|
||||
offset[1] = test_offset_from_addr(addr, g_band);
|
||||
ftl_band_set_addr(g_band, TEST_LBA + 1, addr);
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 2);
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset[0]));
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset[1]));
|
||||
ftl_invalidate_addr(g_band->dev, ppa);
|
||||
ftl_invalidate_addr(g_band->dev, addr);
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 1);
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset[0]));
|
||||
CU_ASSERT_FALSE(spdk_bit_array_get(lba_map->vld, offset[1]));
|
||||
@ -218,60 +218,60 @@ test_invalidate_addr(void)
|
||||
}
|
||||
|
||||
static void
|
||||
test_next_xfer_ppa(void)
|
||||
test_next_xfer_addr(void)
|
||||
{
|
||||
struct ftl_ppa ppa, result, expect;
|
||||
struct ftl_addr addr, result, expect;
|
||||
|
||||
setup_band();
|
||||
/* Verify simple one lbk incremention */
|
||||
ppa = ppa_from_punit(g_range.begin);
|
||||
ppa.zone_id = TEST_BAND_IDX;
|
||||
ppa.offset = 0;
|
||||
expect = ppa;
|
||||
addr = addr_from_punit(g_range.begin);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset = 0;
|
||||
expect = addr;
|
||||
expect.offset = 1;
|
||||
|
||||
result = ftl_band_next_xfer_ppa(g_band, ppa, 1);
|
||||
result = ftl_band_next_xfer_addr(g_band, addr, 1);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
|
||||
/* Verify jumping between zones */
|
||||
expect = ppa_from_punit(g_range.begin + 1);
|
||||
expect = addr_from_punit(g_range.begin + 1);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
result = ftl_band_next_xfer_ppa(g_band, ppa, g_dev->xfer_size);
|
||||
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 = ppa_from_punit(g_range.begin + 1);
|
||||
expect = addr_from_punit(g_range.begin + 1);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = 3;
|
||||
result = ftl_band_next_xfer_ppa(g_band, ppa, g_dev->xfer_size + 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 = ppa_from_punit(g_range.begin);
|
||||
expect = addr_from_punit(g_range.begin);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = g_dev->xfer_size;
|
||||
ppa = ppa_from_punit(g_range.end);
|
||||
ppa.zone_id = TEST_BAND_IDX;
|
||||
result = ftl_band_next_xfer_ppa(g_band, ppa, g_dev->xfer_size);
|
||||
addr = addr_from_punit(g_range.end);
|
||||
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 = ppa_from_punit(g_range.begin);
|
||||
expect = addr_from_punit(g_range.begin);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = g_dev->xfer_size + 2;
|
||||
ppa = ppa_from_punit(g_range.end);
|
||||
ppa.zone_id = TEST_BAND_IDX;
|
||||
result = ftl_band_next_xfer_ppa(g_band, ppa, g_dev->xfer_size + 2);
|
||||
addr = addr_from_punit(g_range.end);
|
||||
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 = ppa_from_punit(g_range.begin);
|
||||
expect = addr_from_punit(g_range.begin);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = g_dev->xfer_size * 5 + 4;
|
||||
ppa = ppa_from_punit(g_range.begin);
|
||||
ppa.zone_id = TEST_BAND_IDX;
|
||||
ppa.offset = g_dev->xfer_size * 2 + 1;
|
||||
result = ftl_band_next_xfer_ppa(g_band, ppa, 3 * g_dev->xfer_size *
|
||||
addr = addr_from_punit(g_range.begin);
|
||||
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 *
|
||||
ftl_dev_num_punits(g_dev) + 3);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
|
||||
@ -279,13 +279,13 @@ test_next_xfer_ppa(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 = ppa_from_punit(g_range.begin + 2);
|
||||
expect = addr_from_punit(g_range.begin + 2);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = g_dev->xfer_size * 5 + 4;
|
||||
ppa = ppa_from_punit(g_range.begin);
|
||||
ppa.zone_id = TEST_BAND_IDX;
|
||||
ppa.offset = g_dev->xfer_size * 2 + 1;
|
||||
result = ftl_band_next_xfer_ppa(g_band, ppa, 3 * g_dev->xfer_size *
|
||||
addr = addr_from_punit(g_range.begin);
|
||||
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 *
|
||||
(ftl_dev_num_punits(g_dev) - 1) + g_dev->xfer_size + 3);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
cleanup_band();
|
||||
@ -308,18 +308,18 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (
|
||||
CU_add_test(suite, "test_band_lbkoff_from_ppa_base",
|
||||
test_band_lbkoff_from_ppa_base) == NULL
|
||||
|| CU_add_test(suite, "test_band_lbkoff_from_ppa_lbk",
|
||||
test_band_lbkoff_from_ppa_lbk) == NULL
|
||||
|| CU_add_test(suite, "test_band_ppa_from_lbkoff",
|
||||
test_band_ppa_from_lbkoff) == NULL
|
||||
CU_add_test(suite, "test_band_lbkoff_from_addr_base",
|
||||
test_band_lbkoff_from_addr_base) == NULL
|
||||
|| CU_add_test(suite, "test_band_lbkoff_from_addr_offset",
|
||||
test_band_lbkoff_from_addr_offset) == NULL
|
||||
|| CU_add_test(suite, "test_band_addr_from_lbkoff",
|
||||
test_band_addr_from_lbkoff) == NULL
|
||||
|| CU_add_test(suite, "test_band_set_addr",
|
||||
test_band_set_addr) == NULL
|
||||
|| CU_add_test(suite, "test_invalidate_addr",
|
||||
test_invalidate_addr) == NULL
|
||||
|| CU_add_test(suite, "test_next_xfer_ppa",
|
||||
test_next_xfer_ppa) == NULL
|
||||
|| CU_add_test(suite, "test_next_xfer_addr",
|
||||
test_next_xfer_addr) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
@ -61,7 +61,7 @@ clean_l2p(void)
|
||||
{
|
||||
size_t l2p_elem_size;
|
||||
|
||||
if (ftl_ppa_packed(g_dev)) {
|
||||
if (ftl_addr_packed(g_dev)) {
|
||||
l2p_elem_size = sizeof(uint32_t);
|
||||
} else {
|
||||
l2p_elem_size = sizeof(uint64_t);
|
||||
@ -81,7 +81,7 @@ setup_l2p_32bit(void)
|
||||
g_dev->ppaf.pu_mask = (1 << 3) - 1;
|
||||
g_dev->ppaf.grp_offset = g_dev->ppaf.pu_offset + 3;
|
||||
g_dev->ppaf.grp_mask = (1 << 2) - 1;
|
||||
g_dev->ppa_len = g_dev->ppaf.grp_offset + 2;
|
||||
g_dev->addr_len = g_dev->ppaf.grp_offset + 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -98,7 +98,7 @@ setup_l2p_64bit(void)
|
||||
g_dev->ppaf.pu_mask = (1 << 3) - 1;
|
||||
g_dev->ppaf.grp_offset = g_dev->ppaf.pu_offset + 3;
|
||||
g_dev->ppaf.grp_mask = (1 << 2) - 1;
|
||||
g_dev->ppa_len = g_dev->ppaf.grp_offset + 2;
|
||||
g_dev->addr_len = g_dev->ppaf.grp_offset + 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -113,146 +113,146 @@ cleanup(void)
|
||||
}
|
||||
|
||||
static void
|
||||
test_ppa_pack32(void)
|
||||
test_addr_pack32(void)
|
||||
{
|
||||
struct ftl_ppa orig = {}, ppa;
|
||||
struct ftl_addr orig = {}, addr;
|
||||
|
||||
/* Check valid address transformation */
|
||||
orig.offset = 4;
|
||||
orig.zone_id = 3;
|
||||
orig.pu = 2;
|
||||
ppa = ftl_ppa_to_packed(g_dev, orig);
|
||||
CU_ASSERT_TRUE(ppa.addr <= UINT32_MAX);
|
||||
CU_ASSERT_FALSE(ppa.pack.cached);
|
||||
ppa = ftl_ppa_from_packed(g_dev, ppa);
|
||||
CU_ASSERT_FALSE(ftl_ppa_invalid(ppa));
|
||||
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
|
||||
addr = ftl_addr_to_packed(g_dev, orig);
|
||||
CU_ASSERT_TRUE(addr.addr <= UINT32_MAX);
|
||||
CU_ASSERT_FALSE(addr.pack.cached);
|
||||
addr = ftl_addr_from_packed(g_dev, addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
|
||||
/* Check invalid address transformation */
|
||||
orig = ftl_to_ppa(FTL_PPA_INVALID);
|
||||
ppa = ftl_ppa_to_packed(g_dev, orig);
|
||||
CU_ASSERT_TRUE(ppa.addr <= UINT32_MAX);
|
||||
ppa = ftl_ppa_from_packed(g_dev, ppa);
|
||||
CU_ASSERT_TRUE(ftl_ppa_invalid(ppa));
|
||||
orig = ftl_to_addr(FTL_ADDR_INVALID);
|
||||
addr = ftl_addr_to_packed(g_dev, orig);
|
||||
CU_ASSERT_TRUE(addr.addr <= UINT32_MAX);
|
||||
addr = ftl_addr_from_packed(g_dev, addr);
|
||||
CU_ASSERT_TRUE(ftl_addr_invalid(addr));
|
||||
|
||||
/* Check cached entry offset transformation */
|
||||
orig.cached = 1;
|
||||
orig.cache_offset = 1024;
|
||||
ppa = ftl_ppa_to_packed(g_dev, orig);
|
||||
CU_ASSERT_TRUE(ppa.addr <= UINT32_MAX);
|
||||
CU_ASSERT_TRUE(ppa.pack.cached);
|
||||
ppa = ftl_ppa_from_packed(g_dev, ppa);
|
||||
CU_ASSERT_FALSE(ftl_ppa_invalid(ppa));
|
||||
CU_ASSERT_TRUE(ftl_ppa_cached(ppa));
|
||||
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
|
||||
addr = ftl_addr_to_packed(g_dev, orig);
|
||||
CU_ASSERT_TRUE(addr.addr <= UINT32_MAX);
|
||||
CU_ASSERT_TRUE(addr.pack.cached);
|
||||
addr = ftl_addr_from_packed(g_dev, addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_TRUE(ftl_addr_cached(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
clean_l2p();
|
||||
}
|
||||
|
||||
static void
|
||||
test_ppa_pack64(void)
|
||||
test_addr_pack64(void)
|
||||
{
|
||||
struct ftl_ppa orig = {}, ppa;
|
||||
struct ftl_addr orig = {}, addr;
|
||||
|
||||
orig.offset = 4;
|
||||
orig.zone_id = 3;
|
||||
orig.pu = 2;
|
||||
|
||||
/* Check valid address transformation */
|
||||
ppa.addr = ftl_ppa_addr_pack(g_dev, orig);
|
||||
ppa = ftl_ppa_addr_unpack(g_dev, ppa.addr);
|
||||
CU_ASSERT_FALSE(ftl_ppa_invalid(ppa));
|
||||
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
|
||||
addr.addr = ftl_addr_addr_pack(g_dev, orig);
|
||||
addr = ftl_addr_addr_unpack(g_dev, addr.addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
|
||||
orig.offset = 0x7ea0be0f;
|
||||
orig.zone_id = 0x6;
|
||||
orig.pu = 0x4;
|
||||
|
||||
ppa.addr = ftl_ppa_addr_pack(g_dev, orig);
|
||||
ppa = ftl_ppa_addr_unpack(g_dev, ppa.addr);
|
||||
CU_ASSERT_FALSE(ftl_ppa_invalid(ppa));
|
||||
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
|
||||
addr.addr = ftl_addr_addr_pack(g_dev, orig);
|
||||
addr = ftl_addr_addr_unpack(g_dev, addr.addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
|
||||
/* Check maximum valid address for ppaf */
|
||||
/* Check maximum valid address for addrf */
|
||||
orig.offset = 0x7fffffff;
|
||||
orig.zone_id = 0xf;
|
||||
orig.pu = 0x7;
|
||||
|
||||
ppa.addr = ftl_ppa_addr_pack(g_dev, orig);
|
||||
ppa = ftl_ppa_addr_unpack(g_dev, ppa.addr);
|
||||
CU_ASSERT_FALSE(ftl_ppa_invalid(ppa));
|
||||
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
|
||||
addr.addr = ftl_addr_addr_pack(g_dev, orig);
|
||||
addr = ftl_addr_addr_unpack(g_dev, addr.addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
clean_l2p();
|
||||
}
|
||||
|
||||
static void
|
||||
test_ppa_trans(void)
|
||||
test_addr_trans(void)
|
||||
{
|
||||
struct ftl_ppa ppa = {}, orig = {};
|
||||
struct ftl_addr addr = {}, orig = {};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < L2P_TABLE_SIZE; ++i) {
|
||||
ppa.offset = i % (g_dev->ppaf.lbk_mask + 1);
|
||||
ppa.zone_id = i % (g_dev->ppaf.chk_mask + 1);
|
||||
ppa.pu = i % (g_dev->ppaf.pu_mask + 1);
|
||||
ftl_l2p_set(g_dev, i, ppa);
|
||||
addr.offset = i % (g_dev->ppaf.lbk_mask + 1);
|
||||
addr.zone_id = i % (g_dev->ppaf.chk_mask + 1);
|
||||
addr.pu = i % (g_dev->ppaf.pu_mask + 1);
|
||||
ftl_l2p_set(g_dev, i, addr);
|
||||
}
|
||||
|
||||
for (i = 0; i < L2P_TABLE_SIZE; ++i) {
|
||||
orig.offset = i % (g_dev->ppaf.lbk_mask + 1);
|
||||
orig.zone_id = i % (g_dev->ppaf.chk_mask + 1);
|
||||
orig.pu = i % (g_dev->ppaf.pu_mask + 1);
|
||||
ppa = ftl_l2p_get(g_dev, i);
|
||||
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
|
||||
addr = ftl_l2p_get(g_dev, i);
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
}
|
||||
clean_l2p();
|
||||
}
|
||||
|
||||
static void
|
||||
test_ppa_invalid(void)
|
||||
test_addr_invalid(void)
|
||||
{
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
size_t i;
|
||||
|
||||
/* Set every other LBA as invalid */
|
||||
for (i = 0; i < L2P_TABLE_SIZE; i += 2) {
|
||||
ftl_l2p_set(g_dev, i, ftl_to_ppa(FTL_PPA_INVALID));
|
||||
ftl_l2p_set(g_dev, i, ftl_to_addr(FTL_ADDR_INVALID));
|
||||
}
|
||||
|
||||
/* Check every even LBA is invalid while others are fine */
|
||||
for (i = 0; i < L2P_TABLE_SIZE; ++i) {
|
||||
ppa = ftl_l2p_get(g_dev, i);
|
||||
addr = ftl_l2p_get(g_dev, i);
|
||||
|
||||
if (i % 2 == 0) {
|
||||
CU_ASSERT_TRUE(ftl_ppa_invalid(ppa));
|
||||
CU_ASSERT_TRUE(ftl_addr_invalid(addr));
|
||||
} else {
|
||||
CU_ASSERT_FALSE(ftl_ppa_invalid(ppa));
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
}
|
||||
}
|
||||
clean_l2p();
|
||||
}
|
||||
|
||||
static void
|
||||
test_ppa_cached(void)
|
||||
test_addr_cached(void)
|
||||
{
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
size_t i;
|
||||
|
||||
/* Set every other LBA is cached */
|
||||
for (i = 0; i < L2P_TABLE_SIZE; i += 2) {
|
||||
ppa.cached = 1;
|
||||
ppa.cache_offset = i;
|
||||
ftl_l2p_set(g_dev, i, ppa);
|
||||
addr.cached = 1;
|
||||
addr.cache_offset = i;
|
||||
ftl_l2p_set(g_dev, i, addr);
|
||||
}
|
||||
|
||||
/* Check every even LBA is cached while others are not */
|
||||
for (i = 0; i < L2P_TABLE_SIZE; ++i) {
|
||||
ppa = ftl_l2p_get(g_dev, i);
|
||||
addr = ftl_l2p_get(g_dev, i);
|
||||
|
||||
if (i % 2 == 0) {
|
||||
CU_ASSERT_TRUE(ftl_ppa_cached(ppa));
|
||||
CU_ASSERT_EQUAL(ppa.offset, i);
|
||||
CU_ASSERT_TRUE(ftl_addr_cached(addr));
|
||||
CU_ASSERT_EQUAL(addr.cache_offset, i);
|
||||
} else {
|
||||
CU_ASSERT_FALSE(ftl_ppa_cached(ppa));
|
||||
CU_ASSERT_FALSE(ftl_addr_cached(addr));
|
||||
}
|
||||
}
|
||||
clean_l2p();
|
||||
@ -268,35 +268,35 @@ main(int argc, char **argv)
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
suite32 = CU_add_suite("ftl_ppa32_suite", setup_l2p_32bit, cleanup);
|
||||
suite32 = CU_add_suite("ftl_addr32_suite", setup_l2p_32bit, cleanup);
|
||||
if (!suite32) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
suite64 = CU_add_suite("ftl_ppa64_suite", setup_l2p_64bit, cleanup);
|
||||
suite64 = CU_add_suite("ftl_addr64_suite", setup_l2p_64bit, cleanup);
|
||||
if (!suite64) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
if (
|
||||
CU_add_test(suite32, "test_ppa_pack",
|
||||
test_ppa_pack32) == NULL
|
||||
|| CU_add_test(suite32, "test_ppa32_invalid",
|
||||
test_ppa_invalid) == NULL
|
||||
|| CU_add_test(suite32, "test_ppa32_trans",
|
||||
test_ppa_trans) == NULL
|
||||
|| CU_add_test(suite32, "test_ppa32_cached",
|
||||
test_ppa_cached) == NULL
|
||||
|| CU_add_test(suite64, "test_ppa64_invalid",
|
||||
test_ppa_invalid) == NULL
|
||||
|| CU_add_test(suite64, "test_ppa64_trans",
|
||||
test_ppa_trans) == NULL
|
||||
|| CU_add_test(suite64, "test_ppa64_cached",
|
||||
test_ppa_cached) == NULL
|
||||
|| CU_add_test(suite64, "test_ppa64_pack",
|
||||
test_ppa_pack64) == NULL
|
||||
CU_add_test(suite32, "test_addr_pack",
|
||||
test_addr_pack32) == NULL
|
||||
|| CU_add_test(suite32, "test_addr32_invalid",
|
||||
test_addr_invalid) == NULL
|
||||
|| CU_add_test(suite32, "test_addr32_trans",
|
||||
test_addr_trans) == NULL
|
||||
|| CU_add_test(suite32, "test_addr32_cached",
|
||||
test_addr_cached) == NULL
|
||||
|| CU_add_test(suite64, "test_addr64_invalid",
|
||||
test_addr_invalid) == NULL
|
||||
|| CU_add_test(suite64, "test_addr64_trans",
|
||||
test_addr_trans) == NULL
|
||||
|| CU_add_test(suite64, "test_addr64_cached",
|
||||
test_addr_cached) == NULL
|
||||
|| CU_add_test(suite64, "test_addr64_pack",
|
||||
test_addr_pack64) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
@ -57,7 +57,7 @@ static struct spdk_ftl_punit_range g_range = {
|
||||
};
|
||||
|
||||
DEFINE_STUB(ftl_dev_tail_md_disk_size, size_t, (const struct spdk_ftl_dev *dev), 1);
|
||||
DEFINE_STUB(ftl_ppa_is_written, bool, (struct ftl_band *band, struct ftl_ppa ppa), true);
|
||||
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));
|
||||
DEFINE_STUB_V(ftl_trace_lba_io_init, (struct spdk_ftl_dev *dev, const struct ftl_io *io));
|
||||
DEFINE_STUB_V(ftl_free_io, (struct ftl_io *io));
|
||||
@ -104,25 +104,25 @@ ftl_band_read_lba_map(struct ftl_band *band, size_t offset,
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ftl_band_lbkoff_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
|
||||
ftl_band_lbkoff_from_addr(struct ftl_band *band, struct ftl_addr addr)
|
||||
{
|
||||
return test_offset_from_ppa(ppa, band);
|
||||
return test_offset_from_addr(addr, band);
|
||||
}
|
||||
|
||||
struct ftl_ppa
|
||||
ftl_band_ppa_from_lbkoff(struct ftl_band *band, uint64_t lbkoff)
|
||||
struct ftl_addr
|
||||
ftl_band_addr_from_lbkoff(struct ftl_band *band, uint64_t lbkoff)
|
||||
{
|
||||
struct ftl_ppa ppa = { .addr = 0 };
|
||||
struct ftl_addr addr = { .addr = 0 };
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
uint64_t punit;
|
||||
|
||||
punit = lbkoff / ftl_dev_lbks_in_zone(dev) + dev->range.begin;
|
||||
|
||||
ppa.offset = lbkoff % ftl_dev_lbks_in_zone(dev);
|
||||
ppa.zone_id = band->id;
|
||||
ppa.pu = punit;
|
||||
addr.offset = lbkoff % ftl_dev_lbks_in_zone(dev);
|
||||
addr.zone_id = band->id;
|
||||
addr.pu = punit;
|
||||
|
||||
return ppa;
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -267,7 +267,7 @@ test_reloc_iter_full(void)
|
||||
struct ftl_reloc *reloc;
|
||||
struct ftl_band_reloc *breloc;
|
||||
struct ftl_band *band;
|
||||
struct ftl_ppa ppa;
|
||||
struct ftl_addr addr;
|
||||
|
||||
setup_reloc(&dev, &reloc, &g_geo, &g_range);
|
||||
|
||||
@ -285,7 +285,7 @@ test_reloc_iter_full(void)
|
||||
(ftl_dev_lbks_in_zone(dev) / reloc->xfer_size);
|
||||
|
||||
for (i = 0; i < num_iters; i++) {
|
||||
num_lbks = ftl_reloc_next_lbks(breloc, &ppa);
|
||||
num_lbks = ftl_reloc_next_lbks(breloc, &addr);
|
||||
CU_ASSERT_EQUAL(num_lbks, reloc->xfer_size);
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ test_reloc_iter_full(void)
|
||||
/* is not divisible by xfer_size */
|
||||
reminder = ftl_dev_lbks_in_zone(dev) % reloc->xfer_size;
|
||||
for (i = 0; i < num_iters; i++) {
|
||||
num_lbks = ftl_reloc_next_lbks(breloc, &ppa);
|
||||
num_lbks = ftl_reloc_next_lbks(breloc, &addr);
|
||||
CU_ASSERT_EQUAL(reminder, num_lbks);
|
||||
}
|
||||
|
||||
|
@ -306,15 +306,15 @@ static void
|
||||
test_rwb_entry_from_offset(void)
|
||||
{
|
||||
struct ftl_rwb_entry *entry;
|
||||
struct ftl_ppa ppa = { .cached = 1 };
|
||||
struct ftl_addr addr = { .cached = 1 };
|
||||
size_t i;
|
||||
|
||||
setup_rwb();
|
||||
for (i = 0; i < g_ut.max_allocable_entries; ++i) {
|
||||
ppa.offset = i;
|
||||
addr.cache_offset = i;
|
||||
|
||||
entry = ftl_rwb_entry_from_offset(g_rwb, i);
|
||||
CU_ASSERT_EQUAL(ppa.offset, entry->pos);
|
||||
CU_ASSERT_EQUAL(addr.cache_offset, entry->pos);
|
||||
}
|
||||
cleanup_rwb();
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ DEFINE_STUB_V(ftl_reloc_add, (struct ftl_reloc *reloc, struct ftl_band *band, si
|
||||
size_t num_lbks, int prio, bool defrag));
|
||||
DEFINE_STUB_V(ftl_trace_write_band, (struct spdk_ftl_dev *dev, const struct ftl_band *band));
|
||||
DEFINE_STUB_V(ftl_trace_submission, (struct spdk_ftl_dev *dev, const struct ftl_io *io,
|
||||
struct ftl_ppa ppa, size_t ppa_cnt));
|
||||
struct ftl_addr addr, size_t addr_cnt));
|
||||
DEFINE_STUB_V(ftl_rwb_get_limits, (struct ftl_rwb *rwb, size_t limit[FTL_RWB_TYPE_MAX]));
|
||||
DEFINE_STUB_V(ftl_io_process_error, (struct ftl_io *io, const struct spdk_nvme_cpl *status));
|
||||
DEFINE_STUB_V(ftl_trace_limits, (struct spdk_ftl_dev *dev, const size_t *limits, size_t num_free));
|
||||
@ -164,7 +164,7 @@ test_wptr(void)
|
||||
|
||||
for (lbk = 0, offset = 0; lbk < ftl_dev_lbks_in_zone(dev) / xfer_size; ++lbk) {
|
||||
for (zone = 0; zone < band->num_zones; ++zone) {
|
||||
CU_ASSERT_EQUAL(wptr->ppa.offset, (lbk * xfer_size));
|
||||
CU_ASSERT_EQUAL(wptr->addr.offset, (lbk * xfer_size));
|
||||
CU_ASSERT_EQUAL(wptr->offset, offset);
|
||||
ftl_wptr_advance(wptr, xfer_size);
|
||||
offset += xfer_size;
|
||||
@ -172,7 +172,7 @@ test_wptr(void)
|
||||
}
|
||||
|
||||
CU_ASSERT_EQUAL(band->state, FTL_BAND_STATE_FULL);
|
||||
CU_ASSERT_EQUAL(wptr->ppa.offset, ftl_dev_lbks_in_zone(dev));
|
||||
CU_ASSERT_EQUAL(wptr->addr.offset, ftl_dev_lbks_in_zone(dev));
|
||||
|
||||
ftl_band_set_state(band, FTL_BAND_STATE_CLOSING);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user