lib/ftl: use pre-allocated iov buffer

Keep an array of iovecs tied to each IO. Internal IOs can have
iov_cnt > 1 without having to allocate additional memory. User's iovec
can now be modified too (e.g. when splitting the request).

Change-Id: Iec73c6dad59acdc331a1461fd7feac085138a8de
Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/455525
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
This commit is contained in:
Konrad Sztyber 2019-05-21 12:24:57 +02:00 committed by Darek Stojaczyk
parent feb2c6be42
commit 1d97387549
5 changed files with 11 additions and 26 deletions

View File

@ -48,9 +48,6 @@
#include "ftl_debug.h"
#include "ftl_reloc.h"
/* Max number of iovecs */
#define FTL_MAX_IOV 1024
struct ftl_wptr {
/* Owner device */
struct spdk_ftl_dev *dev;
@ -1615,7 +1612,7 @@ spdk_ftl_write(struct spdk_ftl_dev *dev, struct spdk_io_channel *ch, uint64_t lb
{
struct ftl_io *io;
if (iov_cnt == 0 || iov_cnt > FTL_MAX_IOV) {
if (iov_cnt == 0 || iov_cnt > FTL_IO_MAX_IOVEC) {
return -EINVAL;
}
@ -1667,7 +1664,7 @@ spdk_ftl_read(struct spdk_ftl_dev *dev, struct spdk_io_channel *ch, uint64_t lba
{
struct ftl_io *io;
if (iov_cnt == 0 || iov_cnt > FTL_MAX_IOV) {
if (iov_cnt == 0 || iov_cnt > FTL_IO_MAX_IOVEC) {
return -EINVAL;
}

View File

@ -75,11 +75,7 @@ ftl_io_dec_req(struct ftl_io *io)
struct iovec *
ftl_io_iovec(struct ftl_io *io)
{
if (io->iov_cnt > 1) {
return io->iov.vector;
} else {
return &io->iov.single;
}
return &io->iov[0];
}
uint64_t
@ -166,8 +162,8 @@ ftl_io_init_iovec(struct ftl_io *io, void *buf, size_t lbk_cnt)
io->lbk_cnt = lbk_cnt;
io->iov_cnt = 1;
io->iov.single.iov_base = buf;
io->iov.single.iov_len = lbk_cnt * PAGE_SIZE;
io->iov[0].iov_base = buf;
io->iov[0].iov_len = lbk_cnt * PAGE_SIZE;
}
void
@ -292,11 +288,8 @@ ftl_io_user_init(struct spdk_io_channel *_ioch, uint64_t lba, size_t lbk_cnt, st
io->lbk_cnt = lbk_cnt;
io->iov_cnt = iov_cnt;
if (iov_cnt > 1) {
io->iov.vector = iov;
} else {
io->iov.single = *iov;
}
assert(iov_cnt < FTL_IO_MAX_IOVEC);
memcpy(io->iov, iov, iov_cnt * sizeof(*iov));
ftl_trace_lba_io_init(io->dev, io);

View File

@ -161,13 +161,8 @@ struct ftl_io {
/* Number of lbks */
size_t lbk_cnt;
union {
/* IO vector table */
struct iovec *vector;
/* Single iovec */
struct iovec single;
} iov;
#define FTL_IO_MAX_IOVEC 64
struct iovec iov[FTL_IO_MAX_IOVEC];
/* Metadata */
void *md;

View File

@ -213,7 +213,7 @@ ftl_reloc_prep(struct ftl_band_reloc *breloc)
static void
ftl_reloc_free_io(struct ftl_band_reloc *breloc, struct ftl_io *io)
{
spdk_dma_free(io->iov.single.iov_base);
spdk_dma_free(io->iov[0].iov_base);
free(io->lba.vector);
spdk_ring_enqueue(breloc->free_queue, (void **)&io, 1);
}

View File

@ -154,7 +154,7 @@ ftl_io_init_internal(const struct ftl_io_init_opts *opts)
io->cb.fn = opts->fn;
io->cb.ctx = io;
io->lbk_cnt = opts->lbk_cnt;
io->iov.single.iov_base = opts->data;
io->iov[0].iov_base = opts->data;
return io;
}