lib/ftl: Zone append support
Zone append command allow to write to the zone with queue depth greater than one. Append location is read during write completion callback. Change-Id: Ie08ce8d31d5d0fb521cdc2b95f3e29b92e02e63f Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471627 Community-CI: SPDK CI Jenkins <sys_sgci@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
This commit is contained in:
parent
b48113b296
commit
55342d972b
@ -93,6 +93,9 @@ struct spdk_ftl_conf {
|
||||
/* Allow for partial recovery from open bands instead of returning error */
|
||||
bool allow_open_bands;
|
||||
|
||||
/* Use append instead of write */
|
||||
bool use_append;
|
||||
|
||||
struct {
|
||||
/* Maximum number of concurrent requests */
|
||||
size_t max_request_cnt;
|
||||
|
@ -164,12 +164,18 @@ static void
|
||||
ftl_io_cmpl_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
|
||||
{
|
||||
struct ftl_io *io = cb_arg;
|
||||
struct spdk_ftl_dev *dev = io->dev;
|
||||
|
||||
if (spdk_unlikely(!success)) {
|
||||
io->status = -EIO;
|
||||
}
|
||||
|
||||
ftl_trace_completion(io->dev, io, FTL_TRACE_COMPLETION_DISK);
|
||||
ftl_trace_completion(dev, io, FTL_TRACE_COMPLETION_DISK);
|
||||
|
||||
if (io->type == FTL_IO_WRITE && ftl_is_append_supported(dev)) {
|
||||
assert(io->parent);
|
||||
io->parent->addr.offset = spdk_bdev_io_get_append_location(bdev_io);
|
||||
}
|
||||
|
||||
ftl_io_dec_req(io);
|
||||
if (ftl_io_done(io)) {
|
||||
@ -1486,7 +1492,7 @@ ftl_io_init_child_write(struct ftl_io *parent, struct ftl_addr addr,
|
||||
.band = parent->band,
|
||||
.size = sizeof(struct ftl_io),
|
||||
.flags = 0,
|
||||
.type = FTL_IO_WRITE,
|
||||
.type = parent->type,
|
||||
.lbk_cnt = dev->xfer_size,
|
||||
.cb_fn = cb,
|
||||
.data = data,
|
||||
@ -1549,10 +1555,18 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
|
||||
|
||||
wptr->num_outstanding++;
|
||||
|
||||
rc = spdk_bdev_write_blocks(dev->base_bdev_desc, ioch->base_ioch,
|
||||
ftl_io_iovec_addr(child),
|
||||
addr.offset,
|
||||
lbk_cnt, ftl_io_cmpl_cb, child);
|
||||
if (ftl_is_append_supported(dev)) {
|
||||
rc = spdk_bdev_zone_append(dev->base_bdev_desc, ioch->base_ioch,
|
||||
ftl_io_iovec_addr(child),
|
||||
ftl_addr_get_zone_slba(dev, addr),
|
||||
lbk_cnt, ftl_io_cmpl_cb, child);
|
||||
} else {
|
||||
rc = spdk_bdev_write_blocks(dev->base_bdev_desc, ioch->base_ioch,
|
||||
ftl_io_iovec_addr(child),
|
||||
addr.offset,
|
||||
lbk_cnt, ftl_io_cmpl_cb, child);
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
wptr->num_outstanding--;
|
||||
ftl_io_fail(child, rc);
|
||||
@ -1581,7 +1595,7 @@ ftl_submit_write(struct ftl_wptr *wptr, struct ftl_io *io)
|
||||
while (io->iov_pos < io->iov_cnt) {
|
||||
/* There are no guarantees of the order of completion of NVMe IO submission queue */
|
||||
/* so wait until zone is not busy before submitting another write */
|
||||
if (wptr->zone->busy) {
|
||||
if (!ftl_is_append_supported(dev) && wptr->zone->busy) {
|
||||
TAILQ_INSERT_TAIL(&wptr->pending_queue, io, retry_entry);
|
||||
rc = -EAGAIN;
|
||||
break;
|
||||
|
@ -326,6 +326,12 @@ ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
|
||||
return ftl_get_num_punits(dev) * ftl_get_num_blocks_in_zone(dev);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ftl_addr_get_zone_slba(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
return addr.offset -= (addr.offset % ftl_get_num_blocks_in_zone(dev));
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ftl_addr_get_band(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
@ -502,4 +508,10 @@ ftl_nv_cache_unpack_lba(uint64_t in_lba, uint64_t *out_lba, unsigned int *phase)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ftl_is_append_supported(const struct spdk_ftl_dev *dev)
|
||||
{
|
||||
return dev->conf.use_append;
|
||||
}
|
||||
|
||||
#endif /* FTL_CORE_H */
|
||||
|
@ -981,6 +981,13 @@ ftl_dev_init_base_bdev(struct spdk_ftl_dev *dev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ftl_is_append_supported(dev) &&
|
||||
!spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_ZONE_APPEND)) {
|
||||
SPDK_ERRLOG("Bdev dosen't support append: %s\n",
|
||||
spdk_bdev_get_name(bdev));
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev->num_bands = block_cnt / (ftl_get_num_punits(dev) * ftl_get_num_blocks_in_zone(dev));
|
||||
dev->addr_len = spdk_u64log2(block_cnt) + 1;
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "ftl/ftl_io.c"
|
||||
|
||||
DEFINE_STUB(ftl_trace_alloc_id, uint64_t, (struct spdk_ftl_dev *dev), 0);
|
||||
DEFINE_STUB(spdk_bdev_io_get_append_location, uint64_t, (struct spdk_bdev_io *bdev_io), 0);
|
||||
DEFINE_STUB_V(ftl_band_acquire_lba_map, (struct ftl_band *band));
|
||||
DEFINE_STUB_V(ftl_band_release_lba_map, (struct ftl_band *band));
|
||||
|
||||
|
@ -71,6 +71,7 @@ DEFINE_STUB(spdk_bdev_zone_management, int, (struct spdk_bdev_desc *desc,
|
||||
struct spdk_io_channel *ch,
|
||||
uint64_t zone_id, enum spdk_bdev_zone_action action,
|
||||
spdk_bdev_io_completion_cb cb, void *cb_arg), 0);
|
||||
DEFINE_STUB(spdk_bdev_io_get_append_location, uint64_t, (struct spdk_bdev_io *bdev_io), 0);
|
||||
|
||||
struct ftl_io *
|
||||
ftl_io_erase_init(struct ftl_band *band, size_t lbk_cnt, ftl_io_fn cb)
|
||||
|
Loading…
Reference in New Issue
Block a user