Commit a2360845 authored by Alexey Marchuk's avatar Alexey Marchuk Committed by Tomasz Zawadzki
Browse files

blob: Add readv/writev_ext functions



These function accept optional spdk_blob_ext_io_opts
structure. If this structure is provided by the user
then readv/writev_ext ops of base dev will be used
in data path

Signed-off-by: default avatarAlexey Marchuk <alexeymar@mellanox.com>
Change-Id: I370dd43f8c56f5752f7a52d0780bcfe3e3ae2d9e
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11371


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
parent 8b25bfce
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -73,6 +73,11 @@ New parameters, `ctrlr_loss_timeout_sec`, `reconnect_delay_sec`, and `fast_io_fa
added to the RPC `bdev_nvme_set_options`. They can be overridden if they are given by the RPC
`bdev_nvme_attach_controller`.

### blobstore

New functions `spdk_blob_io_writev_ext` and `spdk_blob_io_readv_ext` are added. The new functions accept
`spdk_blob_ext_io_opts` structure with extended IO request options.

### event

Added `msg_mempool_size` parameter to `spdk_reactors_init` and `spdk_thread_lib_init_ext`.
+38 −0
Original line number Diff line number Diff line
@@ -809,6 +809,44 @@ void spdk_blob_io_readv(struct spdk_blob *blob, struct spdk_io_channel *channel,
			struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
			spdk_blob_op_complete cb_fn, void *cb_arg);

/**
 * Write the data described by 'iov' to 'length' io_units beginning at 'offset' io_units
 * into the blob. Accepts extended IO request options
 *
 * \param blob Blob to write.
 * \param channel I/O channel used to submit requests.
 * \param iov The pointer points to an array of iovec structures.
 * \param iovcnt The number of buffers.
 * \param offset Offset is in io units from the beginning of the blob.
 * \param length Size of data in io units.
 * \param cb_fn Called when the operation is complete.
 * \param cb_arg Argument passed to function cb_fn.
 * \param io_opts Optional extended IO request options
 */
void spdk_blob_io_writev_ext(struct spdk_blob *blob, struct spdk_io_channel *channel,
			     struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
			     spdk_blob_op_complete cb_fn, void *cb_arg,
			     struct spdk_blob_ext_io_opts *io_opts);

/**
 * Read 'length' io_units starting at 'offset' io_units into the blob into the memory
 * described by 'iov'. Accepts extended IO request options
 *
 * \param blob Blob to read.
 * \param channel I/O channel used to submit requests.
 * \param iov The pointer points to an array of iovec structures.
 * \param iovcnt The number of buffers.
 * \param offset Offset is in io units from the beginning of the blob.
 * \param length Size of data in io units.
 * \param cb_fn Called when the operation is complete.
 * \param cb_arg Argument passed to function cb_fn.
 * \param io_opts Optional extended IO request options
 */
void spdk_blob_io_readv_ext(struct spdk_blob *blob, struct spdk_io_channel *channel,
			    struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
			    spdk_blob_op_complete cb_fn, void *cb_arg,
			    struct spdk_blob_ext_io_opts *io_opts);

/**
 * Unmap 'length' io_units beginning at 'offset' io_units on the blob as unused. Unmapped
 * io_units may allow the underlying storage media to behave more efficiently.
+26 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *   Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
@@ -55,6 +56,17 @@ blob_bs_dev_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
	assert(false);
}

static void
blob_bs_dev_writev_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
		       struct iovec *iov, int iovcnt,
		       uint64_t lba, uint32_t lba_count,
		       struct spdk_bs_dev_cb_args *cb_args,
		       struct spdk_blob_ext_io_opts *ext_opts)
{
	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
	assert(false);
}

static void
blob_bs_dev_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
			 uint64_t lba, uint64_t lba_count,
@@ -102,6 +114,18 @@ blob_bs_dev_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
			   blob_bs_dev_read_cpl, cb_args);
}

static inline void
blob_bs_dev_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
		      struct iovec *iov, int iovcnt,
		      uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args,
		      struct spdk_blob_ext_io_opts *ext_opts)
{
	struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;

	spdk_blob_io_readv_ext(b->blob, channel, iov, iovcnt, lba, lba_count,
			       blob_bs_dev_read_cpl, cb_args, ext_opts);
}

static void
blob_bs_dev_destroy_cpl(void *cb_arg, int bserrno)
{
@@ -140,8 +164,10 @@ bs_create_blob_bs_dev(struct spdk_blob *blob)
	b->bs_dev.destroy = blob_bs_dev_destroy;
	b->bs_dev.write = blob_bs_dev_write;
	b->bs_dev.writev = blob_bs_dev_writev;
	b->bs_dev.writev_ext = blob_bs_dev_writev_ext;
	b->bs_dev.read = blob_bs_dev_read;
	b->bs_dev.readv = blob_bs_dev_readv;
	b->bs_dev.readv_ext = blob_bs_dev_readv_ext;
	b->bs_dev.write_zeroes = blob_bs_dev_write_zeroes;
	b->bs_dev.unmap = blob_bs_dev_unmap;
	b->blob = blob;
+35 −8
Original line number Diff line number Diff line
@@ -2841,6 +2841,7 @@ struct rw_iov_ctx {
	uint64_t io_unit_offset;
	uint64_t io_units_remaining;
	uint64_t io_units_done;
	struct spdk_blob_ext_io_opts *ext_io_opts;
	struct iovec iov[0];
};

@@ -2913,18 +2914,19 @@ rw_iov_split_next(void *cb_arg, int bserrno)
	iov = &ctx->iov[0];

	if (ctx->read) {
		spdk_blob_io_readv(ctx->blob, ctx->channel, iov, iovcnt, io_unit_offset,
				   io_units_count, rw_iov_split_next, ctx);
		spdk_blob_io_readv_ext(ctx->blob, ctx->channel, iov, iovcnt, io_unit_offset,
				       io_units_count, rw_iov_split_next, ctx, ctx->ext_io_opts);
	} else {
		spdk_blob_io_writev(ctx->blob, ctx->channel, iov, iovcnt, io_unit_offset,
				    io_units_count, rw_iov_split_next, ctx);
		spdk_blob_io_writev_ext(ctx->blob, ctx->channel, iov, iovcnt, io_unit_offset,
					io_units_count, rw_iov_split_next, ctx, ctx->ext_io_opts);
	}
}

static void
blob_request_submit_rw_iov(struct spdk_blob *blob, struct spdk_io_channel *_channel,
			   struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
			   spdk_blob_op_complete cb_fn, void *cb_arg, bool read)
			   struct iovec *iov, int iovcnt,
			   uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg, bool read,
			   struct spdk_blob_ext_io_opts *ext_io_opts)
{
	struct spdk_bs_cpl	cpl;

@@ -2997,6 +2999,8 @@ blob_request_submit_rw_iov(struct spdk_blob *blob, struct spdk_io_channel *_chan
				return;
			}

			seq->ext_io_opts = ext_io_opts;

			if (is_allocated) {
				bs_sequence_readv_dev(seq, iov, iovcnt, lba, lba_count, rw_iov_done, NULL);
			} else {
@@ -3013,6 +3017,8 @@ blob_request_submit_rw_iov(struct spdk_blob *blob, struct spdk_io_channel *_chan
					return;
				}

				seq->ext_io_opts = ext_io_opts;

				bs_sequence_writev_dev(seq, iov, iovcnt, lba, lba_count, rw_iov_done, NULL);
			} else {
				/* Queue this operation and allocate the cluster */
@@ -3025,6 +3031,8 @@ blob_request_submit_rw_iov(struct spdk_blob *blob, struct spdk_io_channel *_chan
					return;
				}

				op->ext_io_opts = ext_io_opts;

				bs_allocate_and_copy_cluster(blob, _channel, offset, op);
			}
		}
@@ -3047,6 +3055,7 @@ blob_request_submit_rw_iov(struct spdk_blob *blob, struct spdk_io_channel *_chan
		ctx->io_unit_offset = offset;
		ctx->io_units_remaining = length;
		ctx->io_units_done = 0;
		ctx->ext_io_opts = ext_io_opts;

		rw_iov_split_next(ctx, 0);
	}
@@ -7576,14 +7585,32 @@ void spdk_blob_io_writev(struct spdk_blob *blob, struct spdk_io_channel *channel
			 struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
			 spdk_blob_op_complete cb_fn, void *cb_arg)
{
	blob_request_submit_rw_iov(blob, channel, iov, iovcnt, offset, length, cb_fn, cb_arg, false);
	blob_request_submit_rw_iov(blob, channel, iov, iovcnt, offset, length, cb_fn, cb_arg, false, NULL);
}

void spdk_blob_io_readv(struct spdk_blob *blob, struct spdk_io_channel *channel,
			struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
			spdk_blob_op_complete cb_fn, void *cb_arg)
{
	blob_request_submit_rw_iov(blob, channel, iov, iovcnt, offset, length, cb_fn, cb_arg, true);
	blob_request_submit_rw_iov(blob, channel, iov, iovcnt, offset, length, cb_fn, cb_arg, true, NULL);
}

void
spdk_blob_io_writev_ext(struct spdk_blob *blob, struct spdk_io_channel *channel,
			struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
			spdk_blob_op_complete cb_fn, void *cb_arg, struct spdk_blob_ext_io_opts *io_opts)
{
	blob_request_submit_rw_iov(blob, channel, iov, iovcnt, offset, length, cb_fn, cb_arg, false,
				   io_opts);
}

void
spdk_blob_io_readv_ext(struct spdk_blob *blob, struct spdk_io_channel *channel,
		       struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
		       spdk_blob_op_complete cb_fn, void *cb_arg, struct spdk_blob_ext_io_opts *io_opts)
{
	blob_request_submit_rw_iov(blob, channel, iov, iovcnt, offset, length, cb_fn, cb_arg, true,
				   io_opts);
}

struct spdk_bs_iter_ctx {
+34 −12
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *   Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
@@ -121,6 +122,7 @@ bs_sequence_start(struct spdk_io_channel *_channel,
	set->cb_args.cb_fn = bs_sequence_completion;
	set->cb_args.cb_arg = set;
	set->cb_args.channel = channel->dev_channel;
	set->ext_io_opts = NULL;

	return (spdk_bs_sequence_t *)set;
}
@@ -191,9 +193,15 @@ bs_sequence_readv_bs_dev(spdk_bs_sequence_t *seq, struct spdk_bs_dev *bs_dev,
	set->u.sequence.cb_fn = cb_fn;
	set->u.sequence.cb_arg = cb_arg;

	if (set->ext_io_opts) {
		assert(bs_dev->readv_ext);
		bs_dev->readv_ext(bs_dev, spdk_io_channel_from_ctx(channel), iov, iovcnt, lba, lba_count,
				  &set->cb_args, set->ext_io_opts);
	} else {
		bs_dev->readv(bs_dev, spdk_io_channel_from_ctx(channel), iov, iovcnt, lba, lba_count,
			      &set->cb_args);
	}
}

void
bs_sequence_readv_dev(spdk_bs_sequence_t *seq, struct iovec *iov, int iovcnt,
@@ -207,8 +215,13 @@ bs_sequence_readv_dev(spdk_bs_sequence_t *seq, struct iovec *iov, int iovcnt,

	set->u.sequence.cb_fn = cb_fn;
	set->u.sequence.cb_arg = cb_arg;
	channel->dev->readv(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
			    &set->cb_args);
	if (set->ext_io_opts) {
		assert(channel->dev->readv_ext);
		channel->dev->readv_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
					&set->cb_args, set->ext_io_opts);
	} else {
		channel->dev->readv(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count, &set->cb_args);
	}
}

void
@@ -225,9 +238,15 @@ bs_sequence_writev_dev(spdk_bs_sequence_t *seq, struct iovec *iov, int iovcnt,
	set->u.sequence.cb_fn = cb_fn;
	set->u.sequence.cb_arg = cb_arg;

	if (set->ext_io_opts) {
		assert(channel->dev->writev_ext);
		channel->dev->writev_ext(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
					 &set->cb_args, set->ext_io_opts);
	} else {
		channel->dev->writev(channel->dev, channel->dev_channel, iov, iovcnt, lba, lba_count,
				     &set->cb_args);
	}
}

void
bs_sequence_write_zeroes_dev(spdk_bs_sequence_t *seq,
@@ -438,6 +457,7 @@ bs_user_op_alloc(struct spdk_io_channel *_channel, struct spdk_bs_cpl *cpl,

	set->cpl = *cpl;
	set->channel = channel;
	set->ext_io_opts = NULL;

	args = &set->u.user_op;

@@ -480,14 +500,16 @@ bs_user_op_execute(spdk_bs_user_op_t *op)
					  set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
		break;
	case SPDK_BLOB_READV:
		spdk_blob_io_readv(args->blob, ch, args->payload, args->iovcnt,
		spdk_blob_io_readv_ext(args->blob, ch, args->payload, args->iovcnt,
				       args->offset, args->length,
				   set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
				       set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg,
				       set->ext_io_opts);
		break;
	case SPDK_BLOB_WRITEV:
		spdk_blob_io_writev(args->blob, ch, args->payload, args->iovcnt,
		spdk_blob_io_writev_ext(args->blob, ch, args->payload, args->iovcnt,
					args->offset, args->length,
				    set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg);
					set->cpl.u.blob_basic.cb_fn, set->cpl.u.blob_basic.cb_arg,
					set->ext_io_opts);
		break;
	}
	TAILQ_INSERT_TAIL(&set->channel->reqs, set, link);
Loading