lib/ftl: Change ftl_ppa fields to be zone specific

Remove some Open Channel dependencies from ftl_ppa struct.

Change-Id: Ic088b84c56a928906c6c01c6ef74e69be6d0107f
Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/479549
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Wojciech Malikowski 2020-01-07 08:29:27 -05:00 committed by Tomasz Zawadzki
parent 7083fa3e35
commit 748785c2a9
17 changed files with 160 additions and 160 deletions

View File

@ -172,7 +172,7 @@ ftl_anm_process_log(struct ftl_anm_poller *poller,
}
poller->fn(event);
ppa.chk++;
ppa.zone_id++;
}
return 0;
@ -186,7 +186,7 @@ ftl_anm_in_poller_range(struct ftl_anm_poller *poller,
struct ftl_ppa ppa = ftl_ppa_addr_unpack(dev, log->lba);
char buf[128];
if (ppa.chk >= ftl_dev_num_bands(dev)) {
if (ppa.zone_id >= ftl_dev_num_bands(dev)) {
SPDK_ERRLOG("ANM log contains invalid @ppa: %s\n",
ftl_ppa2str(ppa, buf, sizeof(buf)));
return false;

View File

@ -404,8 +404,8 @@ ftl_band_tail_md_ppa(struct ftl_band *band)
zone = ftl_band_next_zone(band, zone);
}
ppa.lbk = (num_req / band->num_zones) * xfer_size;
ppa.chk = band->id;
ppa.offset = (num_req / band->num_zones) * xfer_size;
ppa.zone_id = band->id;
ppa.pu = zone->punit->start_ppa.pu;
return ppa;
@ -421,7 +421,7 @@ ftl_band_head_md_ppa(struct ftl_band *band)
}
ppa = CIRCLEQ_FIRST(&band->zones)->punit->start_ppa;
ppa.chk = band->id;
ppa.zone_id = band->id;
return ppa;
}
@ -511,8 +511,8 @@ 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)
{
assert(ppa.chk < ftl_dev_num_bands(dev));
return &dev->bands[ppa.chk];
assert(ppa.zone_id < ftl_dev_num_bands(dev));
return &dev->bands[ppa.zone_id];
}
struct ftl_zone *
@ -534,9 +534,9 @@ ftl_band_lbkoff_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
unsigned int punit;
punit = ftl_ppa_flatten_punit(dev, ppa);
assert(ppa.chk == band->id);
assert(ppa.zone_id == band->id);
return punit * ftl_dev_lbks_in_zone(dev) + ppa.lbk;
return punit * ftl_dev_lbks_in_zone(dev) + ppa.offset;
}
struct ftl_ppa
@ -547,13 +547,13 @@ ftl_band_next_xfer_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t num_lbk
unsigned int punit_num;
size_t num_xfers, num_stripes;
assert(ppa.chk == band->id);
assert(ppa.zone_id == band->id);
punit_num = ftl_ppa_flatten_punit(dev, ppa);
zone = &band->zone_buf[punit_num];
num_lbks += (ppa.lbk % dev->xfer_size);
ppa.lbk -= (ppa.lbk % dev->xfer_size);
num_lbks += (ppa.offset % dev->xfer_size);
ppa.offset -= (ppa.offset % dev->xfer_size);
#if defined(DEBUG)
/* Check that the number of zones has not been changed */
@ -568,10 +568,10 @@ 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.lbk += num_stripes * dev->xfer_size;
ppa.offset += num_stripes * dev->xfer_size;
num_lbks -= num_stripes * dev->xfer_size * band->num_zones;
if (ppa.lbk > ftl_dev_lbks_in_zone(dev)) {
if (ppa.offset > ftl_dev_lbks_in_zone(dev)) {
return ftl_to_ppa(FTL_PPA_INVALID);
}
@ -580,8 +580,8 @@ 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.lbk += dev->xfer_size;
if (ppa.lbk > ftl_dev_lbks_in_zone(dev)) {
ppa.offset += dev->xfer_size;
if (ppa.offset > ftl_dev_lbks_in_zone(dev)) {
return ftl_to_ppa(FTL_PPA_INVALID);
}
}
@ -594,8 +594,8 @@ ftl_band_next_xfer_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t num_lbk
}
if (num_lbks) {
ppa.lbk += num_lbks;
if (ppa.lbk > ftl_dev_lbks_in_zone(dev)) {
ppa.offset += num_lbks;
if (ppa.offset > ftl_dev_lbks_in_zone(dev)) {
return ftl_to_ppa(FTL_PPA_INVALID);
}
}
@ -610,10 +610,10 @@ ftl_xfer_offset_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
unsigned int punit_offset = 0;
size_t off, num_stripes, xfer_size = band->dev->xfer_size;
assert(ppa.chk == band->id);
assert(ppa.zone_id == band->id);
num_stripes = (ppa.lbk / xfer_size) * band->num_zones;
off = ppa.lbk % xfer_size;
num_stripes = (ppa.offset / xfer_size) * band->num_zones;
off = ppa.offset % xfer_size;
current_zone = ftl_band_zone_from_ppa(band, ppa);
CIRCLEQ_FOREACH(zone, &band->zones, circleq) {
@ -629,14 +629,14 @@ ftl_xfer_offset_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)
{
struct ftl_ppa ppa = { .ppa = 0 };
struct ftl_ppa ppa = { .addr = 0 };
struct spdk_ftl_dev *dev = band->dev;
uint64_t punit;
punit = lbkoff / ftl_dev_lbks_in_zone(dev) + dev->range.begin;
ppa.lbk = lbkoff % ftl_dev_lbks_in_zone(dev);
ppa.chk = band->id;
ppa.offset = lbkoff % ftl_dev_lbks_in_zone(dev);
ppa.zone_id = band->id;
ppa.pu = punit;
return ppa;

View File

@ -297,9 +297,9 @@ ftl_ppa_read_next_ppa(struct ftl_io *io, struct ftl_ppa *ppa)
/* 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->lbk % dev->xfer_size);
max_lbks = dev->xfer_size - (ppa->offset % dev->xfer_size);
lbk_cnt = spdk_min(ftl_io_iovec_len_left(io), max_lbks);
assert(ppa->lbk / dev->xfer_size == (ppa->lbk + lbk_cnt - 1) / dev->xfer_size);
assert(ppa->offset / dev->xfer_size == (ppa->offset + lbk_cnt - 1) / dev->xfer_size);
} else {
lbk_cnt = ftl_io_iovec_len_left(io);
}
@ -351,7 +351,7 @@ ftl_submit_erase(struct ftl_io *io)
ppa = zone->start_ppa;
}
assert(ppa.lbk == 0);
assert(ppa.offset == 0);
ppa_packed = ftl_ppa_addr_pack(dev, ppa);
ftl_trace_submission(dev, io, ppa, 1);
@ -586,7 +586,7 @@ ftl_wptr_advance(struct ftl_wptr *wptr, size_t xfer_size)
assert(!ftl_ppa_invalid(wptr->ppa));
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "wptr: pu:%d zone:%d, lbk:%u\n",
wptr->ppa.pu, wptr->ppa.chk, wptr->ppa.lbk);
wptr->ppa.pu, wptr->ppa.zone_id, wptr->ppa.offset);
if (wptr->offset >= next_thld && !dev->next_band) {
dev->next_band = ftl_next_write_band(dev);
@ -689,7 +689,7 @@ ftl_cache_lba_valid(struct spdk_ftl_dev *dev, struct ftl_rwb_entry *entry)
}
ppa = ftl_l2p_get(dev, entry->lba);
if (!(ftl_ppa_cached(ppa) && ppa.offset == entry->pos)) {
if (!(ftl_ppa_cached(ppa) && ppa.cache_offset == entry->pos)) {
return false;
}
@ -908,11 +908,11 @@ ftl_ppa_cache_read(struct ftl_io *io, uint64_t lba,
struct ftl_ppa nppa;
int rc = 0;
entry = ftl_rwb_entry_from_offset(rwb, ppa.offset);
entry = ftl_rwb_entry_from_offset(rwb, ppa.cache_offset);
pthread_spin_lock(&entry->lock);
nppa = ftl_l2p_get(io->dev, lba);
if (ppa.ppa != nppa.ppa) {
if (ppa.addr != nppa.addr) {
rc = -1;
goto out;
}
@ -933,7 +933,7 @@ ftl_lba_read_next_ppa(struct ftl_io *io, struct ftl_ppa *ppa)
*ppa = ftl_l2p_get(dev, ftl_io_current_lba(io));
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Read ppa:%lx, lba:%lu\n",
ppa->ppa, ftl_io_current_lba(io));
ppa->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)) {
@ -1148,7 +1148,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.ppa);
SPDK_ERRLOG("Non-volatile cache write failed at %"PRIx64"\n", io->ppa.addr);
io->status = -EIO;
}
@ -1175,14 +1175,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.ppa,
ftl_io_iovec_addr(io), io->md, io->ppa.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.ppa, io->lbk_cnt);
spdk_strerror(-rc), io->ppa.addr, io->lbk_cnt);
spdk_mempool_put(nv_cache->md_pool, io->md);
io->status = -EIO;
ftl_io_complete(io);
@ -1238,8 +1238,8 @@ _ftl_write_nv_cache(void *ctx)
}
/* Reserve area on the write buffer cache */
child->ppa.ppa = ftl_reserve_nv_cache(&dev->nv_cache, &num_lbks, &phase);
if (child->ppa.ppa == FTL_LBA_INVALID) {
child->ppa.addr = ftl_reserve_nv_cache(&dev->nv_cache, &num_lbks, &phase);
if (child->ppa.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);
@ -1362,7 +1362,7 @@ ftl_write_cb(struct ftl_io *io, void *arg, int status)
}
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write ppa:%lu, lba:%lu\n",
entry->ppa.ppa, entry->lba);
entry->ppa.addr, entry->lba);
}
ftl_process_flush(dev, batch);
@ -1401,7 +1401,7 @@ ftl_update_l2p(struct spdk_ftl_dev *dev, const struct ftl_rwb_entry *entry,
if (ftl_ppa_cached(prev_ppa)) {
assert(!ftl_rwb_entry_weak(entry));
prev = ftl_rwb_entry_from_offset(dev->rwb, prev_ppa.offset);
prev = ftl_rwb_entry_from_offset(dev->rwb, prev_ppa.cache_offset);
pthread_spin_lock(&prev->lock);
/* Re-read the L2P under the lock to protect against updates */
@ -1503,7 +1503,7 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
ppa = wptr->ppa;
} else {
assert(io->flags & FTL_IO_DIRECT_ACCESS);
assert(io->ppa.chk == wptr->band->id);
assert(io->ppa.zone_id == wptr->band->id);
ppa = io->ppa;
}
@ -1524,7 +1524,7 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
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.ppa);
rc, ppa.addr);
return -EIO;
}
@ -1658,7 +1658,7 @@ ftl_wptr_process_writes(struct ftl_wptr *wptr)
prev_ppa = 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.offset == entry->pos) {
if (ftl_ppa_cached(prev_ppa) && prev_ppa.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 */
@ -1674,7 +1674,7 @@ ftl_wptr_process_writes(struct ftl_wptr *wptr)
ppa = ftl_band_next_ppa(wptr->band, ppa, 1);
}
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write ppa:%lx, %lx\n", wptr->ppa.ppa,
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write ppa:%lx, %lx\n", wptr->ppa.addr,
ftl_ppa_addr_pack(dev, wptr->ppa));
if (ftl_submit_write(wptr, io)) {
@ -1756,7 +1756,7 @@ ftl_rwb_fill(struct ftl_io *io)
ftl_rwb_entry_fill(entry, io);
ppa.offset = entry->pos;
ppa.cache_offset = entry->pos;
ftl_trace_rwb_fill(dev, io);
ftl_update_l2p(dev, entry, ppa);
@ -2151,7 +2151,7 @@ ftl_ppa_is_written(struct ftl_band *band, struct ftl_ppa ppa)
{
struct ftl_zone *zone = ftl_band_zone_from_ppa(band, ppa);
return ppa.lbk < zone->write_offset;
return ppa.offset < zone->write_offset;
}
static void

View File

@ -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(addr) \
(struct ftl_ppa) { .ppa = (uint64_t)(addr) }
#define ftl_to_ppa(address) \
(struct ftl_ppa) { .addr = (uint64_t)(address) }
#define ftl_to_ppa_packed(addr) \
(struct ftl_ppa) { .pack.ppa = (uint32_t)(addr) }
#define ftl_to_ppa_packed(address) \
(struct ftl_ppa) { .pack.addr = (uint32_t)(address) }
static inline struct spdk_thread *
ftl_get_core_thread(const struct spdk_ftl_dev *dev)
@ -342,7 +342,7 @@ ftl_ppa_packed(const struct spdk_ftl_dev *dev)
static inline int
ftl_ppa_invalid(struct ftl_ppa ppa)
{
return ppa.ppa == ftl_to_ppa(FTL_PPA_INVALID).ppa;
return ppa.addr == ftl_to_ppa(FTL_PPA_INVALID).addr;
}
static inline int
@ -356,8 +356,8 @@ ftl_ppa_addr_pack(const struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
{
uint64_t lbk, chk, pu, grp;
lbk = ppa.lbk;
chk = ppa.chk;
lbk = ppa.offset;
chk = ppa.zone_id;
pu = ppa.pu / dev->geo.num_grp;
grp = ppa.pu % dev->geo.num_grp;
@ -373,8 +373,8 @@ ftl_ppa_addr_unpack(const struct spdk_ftl_dev *dev, uint64_t ppa)
struct ftl_ppa res = {};
unsigned int pu, grp;
res.lbk = (ppa >> dev->ppaf.lbk_offset) & dev->ppaf.lbk_mask;
res.chk = (ppa >> dev->ppaf.chk_offset) & dev->ppaf.chk_mask;
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.pu = grp * dev->geo.num_pu + pu;
@ -391,9 +391,9 @@ ftl_ppa_to_packed(const struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
p = ftl_to_ppa_packed(FTL_PPA_INVALID);
} else if (ftl_ppa_cached(ppa)) {
p.pack.cached = 1;
p.pack.offset = (uint32_t) ppa.offset;
p.pack.cache_offset = (uint32_t) ppa.cache_offset;
} else {
p.pack.ppa = (uint32_t) ftl_ppa_addr_pack(dev, ppa);
p.pack.addr = (uint32_t) ftl_ppa_addr_pack(dev, ppa);
}
return p;
@ -404,13 +404,13 @@ ftl_ppa_from_packed(const struct spdk_ftl_dev *dev, struct ftl_ppa p)
{
struct ftl_ppa ppa = {};
if (p.pack.ppa == (uint32_t)FTL_PPA_INVALID) {
if (p.pack.addr == (uint32_t)FTL_PPA_INVALID) {
ppa = ftl_to_ppa(FTL_PPA_INVALID);
} else if (p.pack.cached) {
ppa.cached = 1;
ppa.offset = p.pack.offset;
ppa.cache_offset = p.pack.cache_offset;
} else {
ppa = ftl_ppa_addr_unpack(dev, p.pack.ppa);
ppa = ftl_ppa_addr_unpack(dev, p.pack.addr);
}
return ppa;
@ -451,7 +451,7 @@ ftl_ppa_in_range(const struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
_ftl_l2p_get(l2p, off, 64)
#define ftl_ppa_cmp(p1, p2) \
((p1).ppa == (p2).ppa)
((p1).addr == (p2).addr)
static inline void
ftl_l2p_set(struct spdk_ftl_dev *dev, uint64_t lba, struct ftl_ppa ppa)
@ -459,9 +459,9 @@ ftl_l2p_set(struct spdk_ftl_dev *dev, uint64_t lba, struct ftl_ppa ppa)
assert(dev->num_lbas > lba);
if (ftl_ppa_packed(dev)) {
_ftl_l2p_set32(dev->l2p, lba, ftl_ppa_to_packed(dev, ppa).ppa);
_ftl_l2p_set32(dev->l2p, lba, ftl_ppa_to_packed(dev, ppa).addr);
} else {
_ftl_l2p_set64(dev->l2p, lba, ppa.ppa);
_ftl_l2p_set64(dev->l2p, lba, ppa.addr);
}
}

View File

@ -79,7 +79,7 @@ ftl_band_validate_md(struct ftl_band *band)
continue;
}
if (ppa_l2p.ppa != ppa_md.ppa) {
if (ppa_l2p.addr != ppa_md.addr) {
valid = false;
break;
}

View File

@ -54,7 +54,7 @@ static inline const char *
ftl_ppa2str(struct ftl_ppa ppa, char *buf, size_t size)
{
snprintf(buf, size, "(pu: %u, chk: %u, lbk: %u)",
ppa.pu, ppa.chk, ppa.lbk);
ppa.pu, ppa.zone_id, ppa.offset);
return buf;
}

View File

@ -212,7 +212,7 @@ ftl_retrieve_chunk_info(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
unsigned int grp = ppa.pu % dev->geo.num_grp;
unsigned int punit = ppa.pu / dev->geo.num_grp;
uint64_t offset = (grp * dev->geo.num_pu + punit) *
dev->geo.num_chk + ppa.chk;
dev->geo.num_chk + ppa.zone_id;
int rc;
rc = spdk_nvme_ctrlr_cmd_get_log_page(dev->ctrlr, SPDK_OCSSD_LOG_CHUNK_INFO, nsid,
@ -246,7 +246,7 @@ ftl_retrieve_punit_chunk_info(struct spdk_ftl_dev *dev, const struct ftl_punit *
struct ftl_ppa chunk_ppa = punit->start_ppa;
char ppa_buf[128];
for (i = 0; i < dev->geo.num_chk; i += num_entries, chunk_ppa.chk += num_entries) {
for (i = 0; i < dev->geo.num_chk; i += num_entries, chunk_ppa.zone_id += num_entries) {
if (num_entries > dev->geo.num_chk - i) {
num_entries = dev->geo.num_chk - i;
}
@ -377,7 +377,7 @@ ftl_dev_init_bands(struct spdk_ftl_dev *dev)
zone->state = ftl_get_zone_state(&info[j]);
zone->punit = punit;
zone->start_ppa = punit->start_ppa;
zone->start_ppa.chk = band->id;
zone->start_ppa.zone_id = band->id;
zone->write_offset = ftl_dev_lbks_in_zone(dev);
if (zone->state != SPDK_BDEV_ZONE_STATE_OFFLINE) {
@ -412,7 +412,7 @@ ftl_dev_init_punits(struct spdk_ftl_dev *dev)
dev->punits[i].dev = dev;
punit = dev->range.begin + i;
dev->punits[i].start_ppa.ppa = 0;
dev->punits[i].start_ppa.addr = 0;
dev->punits[i].start_ppa.pu = punit;
}

View File

@ -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.ppa = FTL_PPA_INVALID;
io->ppa.addr = FTL_PPA_INVALID;
io->cb_fn = fn;
io->cb_ctx = ctx;
io->trace = ftl_trace_alloc_id(dev);

View File

@ -43,40 +43,40 @@
/* Smallest data unit size */
#define FTL_BLOCK_SIZE 4096
/* This structure represents PPA address. It can have one of the following */
/* This structure represents on-disk address. It can have one of the following */
/* formats: */
/* - PPA describing the on-disk address */
/* - offset inside the cache (indicated by the cached flag) */
/* - addr describing the raw address */
/* - cache_offset inside the cache (indicated by the cached flag) */
/* - packed version of the two formats above (can be only used when the */
/* on-disk PPA address can be represented in less than 32 bits) */
/* 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 {
union {
struct {
uint64_t lbk : 32;
uint64_t chk : 16;
uint64_t offset : 32;
uint64_t zone_id: 16;
uint64_t pu : 15;
uint64_t rsvd : 1;
};
struct {
uint64_t offset : 63;
uint64_t cached : 1;
uint64_t cache_offset : 63;
uint64_t cached : 1;
};
struct {
union {
struct {
uint32_t offset : 31;
uint32_t cached : 1;
uint32_t cache_offset : 31;
uint32_t cached : 1;
};
uint32_t ppa;
uint32_t addr;
};
uint32_t rsvd;
} pack;
uint64_t ppa;
uint64_t addr;
};
};

View File

@ -265,7 +265,7 @@ ftl_reloc_write_cb(struct ftl_io *io, void *arg, int status)
}
for (i = 0; i < move->lbk_cnt; ++i) {
ppa.lbk = move->ppa.lbk + i;
ppa.offset = move->ppa.offset + i;
size_t lbkoff = ftl_band_lbkoff_from_ppa(breloc->band, ppa);
ftl_reloc_clr_lbk(breloc, lbkoff);
}
@ -446,7 +446,7 @@ ftl_reloc_io_init(struct ftl_band_reloc *breloc, struct ftl_reloc_move *move,
io->ppa = move->ppa;
if (flags & FTL_IO_VECTOR_LBA) {
for (i = 0; i < io->lbk_cnt; ++i, ++ppa.lbk) {
for (i = 0; i < io->lbk_cnt; ++i, ++ppa.offset) {
lbkoff = ftl_band_lbkoff_from_ppa(breloc->band, ppa);
if (!ftl_band_lbkoff_valid(breloc->band, lbkoff)) {

View File

@ -1164,12 +1164,12 @@ ftl_pad_zone_cb(struct ftl_io *io, void *arg, int status)
goto end;
}
if (io->ppa.lbk + io->lbk_cnt == band->dev->geo.clba) {
if (io->ppa.offset + io->lbk_cnt == band->dev->geo.clba) {
zone = ftl_band_zone_from_ppa(band, io->ppa);
zone->state = SPDK_BDEV_ZONE_STATE_CLOSED;
} else {
struct ftl_ppa ppa = io->ppa;
ppa.lbk += io->lbk_cnt;
ppa.offset += io->lbk_cnt;
new_io = ftl_restore_init_pad_io(rband, io->iov[0].iov_base, ppa);
if (spdk_unlikely(!new_io)) {
restore->pad_status = -ENOMEM;
@ -1224,7 +1224,7 @@ ftl_restore_pad_band(struct ftl_restore_band *rband)
goto error;
}
ppa = band->zone_buf[i].start_ppa;
ppa.lbk = info.wp;
ppa.offset = info.wp;
buffer = spdk_dma_zmalloc(FTL_BLOCK_SIZE * dev->xfer_size, 0, NULL);
if (spdk_unlikely(!buffer)) {

View File

@ -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.ppa, entry->lba);
spdk_trace_record(tpoint_id, entry->trace, 0, entry->ppa.addr, entry->lba);
}
void
@ -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.ppa);
spdk_trace_record(tpoint_id, io->trace, ppa_cnt, 0, ppa.addr);
}
void

View File

@ -114,7 +114,7 @@ test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id)
zone->state = SPDK_BDEV_ZONE_STATE_CLOSED;
zone->punit = &dev->punits[i];
zone->start_ppa = dev->punits[i].start_ppa;
zone->start_ppa.chk = band->id;
zone->start_ppa.zone_id = band->id;
CIRCLEQ_INSERT_TAIL(&band->zones, zone, circleq);
band->num_zones++;
}
@ -154,7 +154,7 @@ test_offset_from_ppa(struct ftl_ppa ppa, struct ftl_band *band)
/* TODO: ftl_ppa_flatten_punit should return uint32_t */
punit = ftl_ppa_flatten_punit(dev, ppa);
CU_ASSERT_EQUAL(ppa.chk, band->id);
CU_ASSERT_EQUAL(ppa.zone_id, band->id);
return punit * ftl_dev_lbks_in_zone(dev) + ppa.lbk;
return punit * ftl_dev_lbks_in_zone(dev) + ppa.offset;
}

View File

@ -96,7 +96,7 @@ test_band_lbkoff_from_ppa_base(void)
setup_band();
for (i = g_range.begin; i < g_range.end; ++i) {
ppa = ppa_from_punit(i);
ppa.chk = TEST_BAND_IDX;
ppa.zone_id = TEST_BAND_IDX;
offset = ftl_band_lbkoff_from_ppa(g_band, ppa);
CU_ASSERT_EQUAL(offset, flat_lun * ftl_dev_lbks_in_zone(g_dev));
@ -115,8 +115,8 @@ test_band_lbkoff_from_ppa_lbk(void)
for (i = g_range.begin; i < g_range.end; ++i) {
for (j = 0; j < g_geo.clba; ++j) {
ppa = ppa_from_punit(i);
ppa.chk = TEST_BAND_IDX;
ppa.lbk = j;
ppa.zone_id = TEST_BAND_IDX;
ppa.offset = j;
offset = ftl_band_lbkoff_from_ppa(g_band, ppa);
@ -137,13 +137,13 @@ test_band_ppa_from_lbkoff(void)
for (i = g_range.begin; i < g_range.end; ++i) {
for (j = 0; j < g_geo.clba; ++j) {
expect = ppa_from_punit(i);
expect.chk = TEST_BAND_IDX;
expect.lbk = j;
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);
CU_ASSERT_EQUAL(ppa.ppa, expect.ppa);
CU_ASSERT_EQUAL(ppa.addr, expect.addr);
}
}
cleanup_band();
@ -159,7 +159,7 @@ test_band_set_addr(void)
setup_band();
lba_map = &g_band->lba_map;
ppa = ppa_from_punit(g_range.begin);
ppa.chk = TEST_BAND_IDX;
ppa.zone_id = TEST_BAND_IDX;
CU_ASSERT_EQUAL(lba_map->num_vld, 0);
@ -192,7 +192,7 @@ test_invalidate_addr(void)
setup_band();
lba_map = &g_band->lba_map;
ppa = ppa_from_punit(g_range.begin);
ppa.chk = TEST_BAND_IDX;
ppa.zone_id = TEST_BAND_IDX;
offset[0] = test_offset_from_ppa(ppa, g_band);
ftl_band_set_addr(g_band, TEST_LBA, ppa);
@ -225,69 +225,69 @@ test_next_xfer_ppa(void)
setup_band();
/* Verify simple one lbk incremention */
ppa = ppa_from_punit(g_range.begin);
ppa.chk = TEST_BAND_IDX;
ppa.lbk = 0;
ppa.zone_id = TEST_BAND_IDX;
ppa.offset = 0;
expect = ppa;
expect.lbk = 1;
expect.offset = 1;
result = ftl_band_next_xfer_ppa(g_band, ppa, 1);
CU_ASSERT_EQUAL(result.ppa, expect.ppa);
CU_ASSERT_EQUAL(result.addr, expect.addr);
/* Verify jumping between zones */
expect = ppa_from_punit(g_range.begin + 1);
expect.chk = TEST_BAND_IDX;
expect.zone_id = TEST_BAND_IDX;
result = ftl_band_next_xfer_ppa(g_band, ppa, g_dev->xfer_size);
CU_ASSERT_EQUAL(result.ppa, expect.ppa);
CU_ASSERT_EQUAL(result.addr, expect.addr);
/* Verify jumping works with unaligned offsets */
expect = ppa_from_punit(g_range.begin + 1);
expect.chk = TEST_BAND_IDX;
expect.lbk = 3;
expect.zone_id = TEST_BAND_IDX;
expect.offset = 3;
result = ftl_band_next_xfer_ppa(g_band, ppa, g_dev->xfer_size + 3);
CU_ASSERT_EQUAL(result.ppa, expect.ppa);
CU_ASSERT_EQUAL(result.addr, expect.addr);
/* Verify jumping from last zone to the first one */
expect = ppa_from_punit(g_range.begin);
expect.chk = TEST_BAND_IDX;
expect.lbk = g_dev->xfer_size;
expect.zone_id = TEST_BAND_IDX;
expect.offset = g_dev->xfer_size;
ppa = ppa_from_punit(g_range.end);
ppa.chk = TEST_BAND_IDX;
ppa.zone_id = TEST_BAND_IDX;
result = ftl_band_next_xfer_ppa(g_band, ppa, g_dev->xfer_size);
CU_ASSERT_EQUAL(result.ppa, expect.ppa);
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.chk = TEST_BAND_IDX;
expect.lbk = g_dev->xfer_size + 2;
expect.zone_id = TEST_BAND_IDX;
expect.offset = g_dev->xfer_size + 2;
ppa = ppa_from_punit(g_range.end);
ppa.chk = TEST_BAND_IDX;
ppa.zone_id = TEST_BAND_IDX;
result = ftl_band_next_xfer_ppa(g_band, ppa, g_dev->xfer_size + 2);
CU_ASSERT_EQUAL(result.ppa, expect.ppa);
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.chk = TEST_BAND_IDX;
expect.lbk = g_dev->xfer_size * 5 + 4;
expect.zone_id = TEST_BAND_IDX;
expect.offset = g_dev->xfer_size * 5 + 4;
ppa = ppa_from_punit(g_range.begin);
ppa.chk = TEST_BAND_IDX;
ppa.lbk = g_dev->xfer_size * 2 + 1;
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 *
ftl_dev_num_punits(g_dev) + 3);
CU_ASSERT_EQUAL(result.ppa, expect.ppa);
CU_ASSERT_EQUAL(result.addr, expect.addr);
/* Remove one zone and verify it's skipped properly */
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.chk = TEST_BAND_IDX;
expect.lbk = g_dev->xfer_size * 5 + 4;
expect.zone_id = TEST_BAND_IDX;
expect.offset = g_dev->xfer_size * 5 + 4;
ppa = ppa_from_punit(g_range.begin);
ppa.chk = TEST_BAND_IDX;
ppa.lbk = g_dev->xfer_size * 2 + 1;
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 *
(ftl_dev_num_punits(g_dev) - 1) + g_dev->xfer_size + 3);
CU_ASSERT_EQUAL(result.ppa, expect.ppa);
CU_ASSERT_EQUAL(result.addr, expect.addr);
cleanup_band();
}

View File

@ -118,33 +118,33 @@ test_ppa_pack32(void)
struct ftl_ppa orig = {}, ppa;
/* Check valid address transformation */
orig.lbk = 4;
orig.chk = 3;
orig.offset = 4;
orig.zone_id = 3;
orig.pu = 2;
ppa = ftl_ppa_to_packed(g_dev, orig);
CU_ASSERT_TRUE(ppa.ppa <= UINT32_MAX);
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.ppa, orig.ppa);
CU_ASSERT_EQUAL(ppa.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.ppa <= UINT32_MAX);
CU_ASSERT_TRUE(ppa.addr <= UINT32_MAX);
ppa = ftl_ppa_from_packed(g_dev, ppa);
CU_ASSERT_TRUE(ftl_ppa_invalid(ppa));
/* Check cached entry offset transformation */
orig.cached = 1;
orig.offset = 1024;
orig.cache_offset = 1024;
ppa = ftl_ppa_to_packed(g_dev, orig);
CU_ASSERT_TRUE(ppa.ppa <= UINT32_MAX);
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.ppa, orig.ppa);
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
clean_l2p();
}
@ -153,34 +153,34 @@ test_ppa_pack64(void)
{
struct ftl_ppa orig = {}, ppa;
orig.lbk = 4;
orig.chk = 3;
orig.offset = 4;
orig.zone_id = 3;
orig.pu = 2;
/* Check valid address transformation */
ppa.ppa = ftl_ppa_addr_pack(g_dev, orig);
ppa = ftl_ppa_addr_unpack(g_dev, ppa.ppa);
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.ppa, orig.ppa);
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
orig.lbk = 0x7ea0be0f;
orig.chk = 0x6;
orig.offset = 0x7ea0be0f;
orig.zone_id = 0x6;
orig.pu = 0x4;
ppa.ppa = ftl_ppa_addr_pack(g_dev, orig);
ppa = ftl_ppa_addr_unpack(g_dev, ppa.ppa);
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.ppa, orig.ppa);
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
/* Check maximum valid address for ppaf */
orig.lbk = 0x7fffffff;
orig.chk = 0xf;
orig.offset = 0x7fffffff;
orig.zone_id = 0xf;
orig.pu = 0x7;
ppa.ppa = ftl_ppa_addr_pack(g_dev, orig);
ppa = ftl_ppa_addr_unpack(g_dev, ppa.ppa);
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.ppa, orig.ppa);
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
clean_l2p();
}
@ -191,18 +191,18 @@ test_ppa_trans(void)
size_t i;
for (i = 0; i < L2P_TABLE_SIZE; ++i) {
ppa.lbk = i % (g_dev->ppaf.lbk_mask + 1);
ppa.chk = i % (g_dev->ppaf.chk_mask + 1);
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);
}
for (i = 0; i < L2P_TABLE_SIZE; ++i) {
orig.lbk = i % (g_dev->ppaf.lbk_mask + 1);
orig.chk = i % (g_dev->ppaf.chk_mask + 1);
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.ppa, orig.ppa);
CU_ASSERT_EQUAL(ppa.addr, orig.addr);
}
clean_l2p();
}
@ -240,7 +240,7 @@ test_ppa_cached(void)
/* Set every other LBA is cached */
for (i = 0; i < L2P_TABLE_SIZE; i += 2) {
ppa.cached = 1;
ppa.offset = i;
ppa.cache_offset = i;
ftl_l2p_set(g_dev, i, ppa);
}

View File

@ -112,14 +112,14 @@ 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)
{
struct ftl_ppa ppa = { .ppa = 0 };
struct ftl_ppa ppa = { .addr = 0 };
struct spdk_ftl_dev *dev = band->dev;
uint64_t punit;
punit = lbkoff / ftl_dev_lbks_in_zone(dev) + dev->range.begin;
ppa.lbk = lbkoff % ftl_dev_lbks_in_zone(dev);
ppa.chk = band->id;
ppa.offset = lbkoff % ftl_dev_lbks_in_zone(dev);
ppa.zone_id = band->id;
ppa.pu = punit;
return ppa;

View File

@ -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.lbk, (lbk * xfer_size));
CU_ASSERT_EQUAL(wptr->ppa.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.lbk, ftl_dev_lbks_in_zone(dev));
CU_ASSERT_EQUAL(wptr->ppa.offset, ftl_dev_lbks_in_zone(dev));
ftl_band_set_state(band, FTL_BAND_STATE_CLOSING);