lib/ftl: use parent's iovecs during child initialization
Fill in the child's iovec during its initialization by calculating it based on the parent's iovecs and the request's block offset. Change-Id: I61a1d5cf8a1ceae71e996d50db31077c43c4e3d9 Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/898 Reviewed-by: Wojciech Malikowski <wojciech.malikowski@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Maciej Szczepaniak <maciej.szczepaniak@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
4a3bf3a942
commit
f4e42560b4
@ -1183,13 +1183,7 @@ ftl_alloc_io_nv_cache(struct ftl_io *parent, size_t num_blocks)
|
||||
struct ftl_io_init_opts opts = {
|
||||
.dev = parent->dev,
|
||||
.parent = parent,
|
||||
.iovs = {
|
||||
{
|
||||
.iov_base = ftl_io_iovec_addr(parent),
|
||||
.iov_len = num_blocks * FTL_BLOCK_SIZE,
|
||||
}
|
||||
},
|
||||
.iovcnt = 1,
|
||||
.iovcnt = 0,
|
||||
.num_blocks = num_blocks,
|
||||
.flags = parent->flags | FTL_IO_CACHE,
|
||||
};
|
||||
@ -1520,8 +1514,7 @@ ftl_update_l2p(struct spdk_ftl_dev *dev, const struct ftl_rwb_entry *entry,
|
||||
}
|
||||
|
||||
static struct ftl_io *
|
||||
ftl_io_init_child_write(struct ftl_io *parent, struct ftl_addr addr,
|
||||
void *data, void *md, ftl_io_fn cb)
|
||||
ftl_io_init_child_write(struct ftl_io *parent, struct ftl_addr addr, ftl_io_fn cb)
|
||||
{
|
||||
struct ftl_io *io;
|
||||
struct spdk_ftl_dev *dev = parent->dev;
|
||||
@ -1536,14 +1529,7 @@ ftl_io_init_child_write(struct ftl_io *parent, struct ftl_addr addr,
|
||||
.type = parent->type,
|
||||
.num_blocks = dev->xfer_size,
|
||||
.cb_fn = cb,
|
||||
.iovs = {
|
||||
{
|
||||
.iov_base = data,
|
||||
.iov_len = dev->xfer_size * FTL_BLOCK_SIZE,
|
||||
}
|
||||
},
|
||||
.iovcnt = 1,
|
||||
.md = md,
|
||||
.iovcnt = 0,
|
||||
};
|
||||
|
||||
io = ftl_io_init_internal(&opts);
|
||||
@ -1598,8 +1584,7 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io)
|
||||
}
|
||||
|
||||
/* Split IO to child requests and release zone immediately after child is completed */
|
||||
child = ftl_io_init_child_write(io, addr, ftl_io_iovec_addr(io),
|
||||
ftl_io_get_md(io), ftl_io_child_write_cb);
|
||||
child = ftl_io_init_child_write(io, addr, ftl_io_child_write_cb);
|
||||
if (!child) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
@ -158,80 +158,30 @@ ftl_io_iovec_len_left(struct ftl_io *io)
|
||||
}
|
||||
|
||||
static void
|
||||
_ftl_io_init_iovec(struct ftl_io *io, const struct iovec *iov, size_t iov_cnt, size_t num_blocks)
|
||||
ftl_io_init_iovec(struct ftl_io *io, const struct iovec *iov, size_t iov_cnt, size_t iov_off,
|
||||
size_t num_blocks)
|
||||
{
|
||||
size_t iov_off;
|
||||
size_t offset = 0, num_left;
|
||||
|
||||
io->iov_pos = 0;
|
||||
io->iov_cnt = iov_cnt;
|
||||
io->iov_cnt = 0;
|
||||
io->num_blocks = num_blocks;
|
||||
|
||||
memcpy(io->iov, iov, iov_cnt * sizeof(*iov));
|
||||
while (offset < num_blocks) {
|
||||
assert(io->iov_cnt < FTL_IO_MAX_IOVEC && io->iov_cnt < iov_cnt);
|
||||
|
||||
if (num_blocks == 0) {
|
||||
for (iov_off = 0; iov_off < iov_cnt; ++iov_off) {
|
||||
io->num_blocks += iov[iov_off].iov_len / FTL_BLOCK_SIZE;
|
||||
}
|
||||
num_left = spdk_min(iov[io->iov_cnt].iov_len / FTL_BLOCK_SIZE - iov_off,
|
||||
num_blocks);
|
||||
io->iov[io->iov_cnt].iov_base = (char *)iov[io->iov_cnt].iov_base +
|
||||
iov_off * FTL_BLOCK_SIZE;
|
||||
io->iov[io->iov_cnt].iov_len = num_left * FTL_BLOCK_SIZE;
|
||||
|
||||
offset += num_left;
|
||||
io->iov_cnt++;
|
||||
iov_off = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void _ftl_io_free(struct ftl_io *io);
|
||||
|
||||
static int
|
||||
ftl_io_add_child(struct ftl_io *io, const struct iovec *iov, size_t iov_cnt)
|
||||
{
|
||||
struct ftl_io *child;
|
||||
|
||||
child = ftl_io_alloc_child(io);
|
||||
if (spdk_unlikely(!child)) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
_ftl_io_init_iovec(child, iov, iov_cnt, 0);
|
||||
|
||||
if (io->flags & FTL_IO_VECTOR_LBA) {
|
||||
child->lba.vector = io->lba.vector + io->num_blocks;
|
||||
} else {
|
||||
child->lba.single = io->lba.single + io->num_blocks;
|
||||
}
|
||||
|
||||
io->num_blocks += child->num_blocks;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ftl_io_init_iovec(struct ftl_io *io, const struct iovec *iov, size_t iov_cnt, size_t num_blocks)
|
||||
{
|
||||
struct ftl_io *child;
|
||||
size_t iov_off = 0, iov_left;
|
||||
int rc;
|
||||
|
||||
if (spdk_likely(iov_cnt <= FTL_IO_MAX_IOVEC)) {
|
||||
_ftl_io_init_iovec(io, iov, iov_cnt, num_blocks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (iov_off < iov_cnt) {
|
||||
iov_left = spdk_min(iov_cnt - iov_off, FTL_IO_MAX_IOVEC);
|
||||
|
||||
rc = ftl_io_add_child(io, &iov[iov_off], iov_left);
|
||||
if (spdk_unlikely(rc != 0)) {
|
||||
while ((child = LIST_FIRST(&io->children))) {
|
||||
assert(LIST_EMPTY(&child->children));
|
||||
LIST_REMOVE(child, child_entry);
|
||||
_ftl_io_free(child);
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
iov_off += iov_left;
|
||||
}
|
||||
|
||||
assert(io->num_blocks == num_blocks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ftl_io_shrink_iovec(struct ftl_io *io, size_t num_blocks)
|
||||
{
|
||||
@ -275,6 +225,8 @@ ftl_io_init_internal(const struct ftl_io_init_opts *opts)
|
||||
struct ftl_io *io = opts->io;
|
||||
struct ftl_io *parent = opts->parent;
|
||||
struct spdk_ftl_dev *dev = opts->dev;
|
||||
const struct iovec *iov;
|
||||
size_t iov_cnt, iov_off;
|
||||
|
||||
if (!io) {
|
||||
if (parent) {
|
||||
@ -302,13 +254,19 @@ ftl_io_init_internal(const struct ftl_io_init_opts *opts)
|
||||
} else {
|
||||
io->lba.single = parent->lba.single + parent->pos;
|
||||
}
|
||||
|
||||
iov = &parent->iov[parent->iov_pos];
|
||||
iov_cnt = parent->iov_cnt - parent->iov_pos;
|
||||
iov_off = parent->iov_off;
|
||||
} else {
|
||||
iov = &opts->iovs[0];
|
||||
iov_cnt = opts->iovcnt;
|
||||
iov_off = 0;
|
||||
}
|
||||
|
||||
if (ftl_io_init_iovec(io, opts->iovs, opts->iovcnt, opts->num_blocks)) {
|
||||
if (!opts->io) {
|
||||
ftl_io_free(io);
|
||||
}
|
||||
return NULL;
|
||||
/* Some requests (zone resets) do not use iovecs */
|
||||
if (iov_cnt > 0) {
|
||||
ftl_io_init_iovec(io, iov, iov_cnt, iov_off, opts->num_blocks);
|
||||
}
|
||||
|
||||
if (opts->flags & FTL_IO_VECTOR_LBA) {
|
||||
|
Loading…
Reference in New Issue
Block a user