Commit aba66c06 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Jim Harris
Browse files

lib/ftl: added ftl_io_shrink_iovec



This function can be used to reduce the number of iovecs on exisiting IO
structure. It's useful when only the maximum number of iovecs is known
at the ftl_io allocation time.

Change-Id: Ief06634446c65889401f5e0b07b2d1ce7912af34
Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/450630


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
parent c139a7d9
Loading
Loading
Loading
Loading
+34 −14
Original line number Diff line number Diff line
@@ -157,32 +157,52 @@ ftl_io_iovec_len_left(struct ftl_io *io)
	return iov[io->iov_pos].iov_len / PAGE_SIZE - io->iov_off;
}

int
ftl_io_init_iovec(struct ftl_io *io, void *buf,
		  size_t iov_cnt, size_t req_size)
static void
_ftl_io_init_iovec(struct ftl_io *io, void *buf, size_t iov_cnt, size_t req_size)
{
	struct iovec *iov;
	size_t i;

	if (iov_cnt > 1) {
		iov = io->iov.vector = calloc(iov_cnt, sizeof(*iov));
		if (!iov) {
			return -ENOMEM;
		}
	} else {
		iov = &io->iov.single;
	}

	io->iov_pos = 0;
	io->iov_cnt = iov_cnt;
	io->lbk_cnt = iov_cnt * req_size;

	iov = ftl_io_iovec(io);
	for (i = 0; i < iov_cnt; ++i) {
		iov[i].iov_base = (char *)buf + i * req_size * PAGE_SIZE;
		iov[i].iov_len = req_size * PAGE_SIZE;
	}
}

static int
ftl_io_init_iovec(struct ftl_io *io, void *buf, size_t iov_cnt, size_t req_size)
{
	if (iov_cnt > 1) {
		io->iov.vector = calloc(iov_cnt, sizeof(struct iovec));
		if (!io->iov.vector) {
			return -ENOMEM;
		}
	}

	_ftl_io_init_iovec(io, buf, iov_cnt, req_size);

	return 0;
}

void
ftl_io_shrink_iovec(struct ftl_io *io, char *buf, size_t iov_cnt, size_t req_size)
{
	assert(io->iov_cnt >= iov_cnt);
	assert(io->lbk_cnt >= iov_cnt * req_size);
	assert(io->pos == 0 && io->iov_pos == 0 && io->iov_off == 0);

	if (iov_cnt == 1 && io->iov_cnt > 1) {
		free(io->iov.vector);
	}

	_ftl_io_init_iovec(io, buf, iov_cnt, req_size);
}

static void
ftl_io_init(struct ftl_io *io, struct spdk_ftl_dev *dev,
	    spdk_ftl_fn fn, void *ctx, int flags, int type)
@@ -218,7 +238,6 @@ ftl_io_init_internal(const struct ftl_io_init_opts *opts)
	ftl_io_clear(io);
	ftl_io_init(io, dev, opts->fn, io, opts->flags | FTL_IO_INTERNAL, opts->type);

	io->lbk_cnt = opts->iov_cnt * opts->req_size;
	io->rwb_batch = opts->rwb_batch;
	io->band = opts->band;
	io->md = opts->md;
@@ -451,9 +470,10 @@ void
ftl_io_clear(struct ftl_io *io)
{
	io->pos = 0;
	io->req_cnt = 0;
	io->iov_pos = 0;
	io->iov_off = 0;
	io->done = false;
	io->req_cnt = 0;
	io->flags = 0;
	io->rwb_batch = NULL;
	io->band = NULL;
+1 −2
Original line number Diff line number Diff line
@@ -274,8 +274,6 @@ void ftl_io_advance(struct ftl_io *io, size_t lbk_cnt);
size_t ftl_iovec_num_lbks(struct iovec *iov, size_t iov_cnt);
void *ftl_io_iovec_addr(struct ftl_io *io);
size_t ftl_io_iovec_len_left(struct ftl_io *io);
int ftl_io_init_iovec(struct ftl_io *io, void *buf,
		      size_t iov_cnt, size_t req_size);
struct ftl_io *ftl_io_init_internal(const struct ftl_io_init_opts *opts);
struct ftl_io *ftl_io_rwb_init(struct spdk_ftl_dev *dev, struct ftl_band *band,
			       struct ftl_rwb_batch *entry, spdk_ftl_fn cb);
@@ -285,6 +283,7 @@ void ftl_io_user_init(struct spdk_ftl_dev *dev, struct ftl_io *io, uint64_t lba,
		      spdk_ftl_fn fn, void *cb_arg, int type);
void *ftl_io_get_md(const struct ftl_io *io);
void ftl_io_complete(struct ftl_io *io);
void ftl_io_shrink_iovec(struct ftl_io *io, char *buf, size_t iov_cnt, size_t req_size);
void ftl_io_process_error(struct ftl_io *io, const struct spdk_nvme_cpl *status);

#endif /* FTL_IO_H */