bdev: refactor ext opts checks
Move check if opts needs copy to its own function. Move check if opts is valid into its own function. Signed-off-by: Jonas Pfefferle <pepperjo@japf.ch> Change-Id: Ie006ddd0b642eb97aaa3ab13890800322dee7a42 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12571 Community-CI: Mellanox Build Bot Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
parent
ad3634af31
commit
e0c4bba399
127
lib/bdev/bdev.c
127
lib/bdev/bdev.c
@ -2921,6 +2921,55 @@ bdev_io_submit(struct spdk_bdev_io *bdev_io)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_bdev_io_copy_ext_opts(struct spdk_bdev_io *bdev_io, struct spdk_bdev_ext_io_opts *opts)
|
||||
{
|
||||
struct spdk_bdev_ext_io_opts *opts_copy = &bdev_io->internal.ext_opts_copy;
|
||||
|
||||
memcpy(opts_copy, opts, opts->size);
|
||||
bdev_io->internal.ext_opts_copy.metadata = bdev_io->u.bdev.md_buf;
|
||||
/* Save pointer to the copied ext_opts which will be used by bdev modules */
|
||||
bdev_io->u.bdev.ext_opts = opts_copy;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_bdev_io_ext_use_bounce_buffer(struct spdk_bdev_io *bdev_io)
|
||||
{
|
||||
/* bdev doesn't support memory domains, thereby buffers in this IO request can't
|
||||
* be accessed directly. It is needed to allocate buffers before issuing IO operation.
|
||||
* For write operation we need to pull buffers from memory domain before submitting IO.
|
||||
* Once read operation completes, we need to use memory_domain push functionality to
|
||||
* update data in original memory domain IO buffer
|
||||
* This IO request will go through a regular IO flow, so clear memory domains pointers in
|
||||
* the copied ext_opts */
|
||||
bdev_io->internal.ext_opts_copy.memory_domain = NULL;
|
||||
bdev_io->internal.ext_opts_copy.memory_domain_ctx = NULL;
|
||||
_bdev_memory_domain_io_get_buf(bdev_io, _bdev_memory_domain_get_io_cb,
|
||||
bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_bdev_io_submit_ext(struct spdk_bdev_desc *desc, struct spdk_bdev_io *bdev_io,
|
||||
struct spdk_bdev_ext_io_opts *opts, bool copy_opts)
|
||||
{
|
||||
if (opts) {
|
||||
bool use_pull_push = opts->memory_domain && !desc->memory_domains_supported;
|
||||
assert(opts->size <= sizeof(*opts));
|
||||
/*
|
||||
* copy if size is smaller than opts struct to avoid having to check size
|
||||
* on every access to bdev_io->u.bdev.ext_opts
|
||||
*/
|
||||
if (copy_opts || use_pull_push) {
|
||||
_bdev_io_copy_ext_opts(bdev_io, opts);
|
||||
if (use_pull_push) {
|
||||
_bdev_io_ext_use_bounce_buffer(bdev_io);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
bdev_io_submit(bdev_io);
|
||||
}
|
||||
|
||||
static void
|
||||
bdev_io_submit_reset(struct spdk_bdev_io *bdev_io)
|
||||
{
|
||||
@ -4091,33 +4140,6 @@ _bdev_io_check_md_buf(const struct iovec *iovs, const void *md_buf)
|
||||
return _is_buf_allocated(iovs) == (md_buf != NULL);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_bdev_io_copy_ext_opts(struct spdk_bdev_io *bdev_io, struct spdk_bdev_ext_io_opts *opts)
|
||||
{
|
||||
struct spdk_bdev_ext_io_opts *opts_copy = &bdev_io->internal.ext_opts_copy;
|
||||
|
||||
memcpy(opts_copy, opts, opts->size);
|
||||
bdev_io->internal.ext_opts_copy.metadata = bdev_io->u.bdev.md_buf;
|
||||
/* Save pointer to the copied ext_opts which will be used by bdev modules */
|
||||
bdev_io->u.bdev.ext_opts = opts_copy;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_bdev_io_ext_use_bounce_buffer(struct spdk_bdev_io *bdev_io)
|
||||
{
|
||||
/* bdev doesn't support memory domains, thereby buffers in this IO request can't
|
||||
* be accessed directly. It is needed to allocate buffers before issuing IO operation.
|
||||
* For write operation we need to pull buffers from memory domain before submitting IO.
|
||||
* Once read operation completes, we need to use memory_domain push functionality to
|
||||
* update data in original memory domain IO buffer
|
||||
* This IO request will go through a regular IO flow, so clear memory domains pointers in
|
||||
* the copied ext_opts */
|
||||
bdev_io->internal.ext_opts_copy.memory_domain = NULL;
|
||||
bdev_io->internal.ext_opts_copy.memory_domain_ctx = NULL;
|
||||
_bdev_memory_domain_io_get_buf(bdev_io, _bdev_memory_domain_get_io_cb,
|
||||
bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
|
||||
}
|
||||
|
||||
static int
|
||||
bdev_read_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, void *buf,
|
||||
void *md_buf, uint64_t offset_blocks, uint64_t num_blocks,
|
||||
@ -4244,20 +4266,7 @@ bdev_readv_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *c
|
||||
bdev_io->internal.ext_opts = opts;
|
||||
bdev_io->u.bdev.ext_opts = opts;
|
||||
|
||||
if (opts) {
|
||||
bool use_pull_push = opts->memory_domain && !desc->memory_domains_supported;
|
||||
|
||||
assert(opts->size <= sizeof(*opts));
|
||||
if (copy_opts || use_pull_push) {
|
||||
_bdev_io_copy_ext_opts(bdev_io, opts);
|
||||
if (use_pull_push) {
|
||||
_bdev_io_ext_use_bounce_buffer(bdev_io);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bdev_io_submit(bdev_io);
|
||||
_bdev_io_submit_ext(desc, bdev_io, opts, copy_opts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -4289,6 +4298,15 @@ spdk_bdev_readv_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_chann
|
||||
num_blocks, cb, cb_arg, NULL, false);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_bdev_io_check_opts(struct spdk_bdev_ext_io_opts *opts, struct iovec *iov)
|
||||
{
|
||||
return opts->size > 0 &&
|
||||
opts->size <= sizeof(*opts) &&
|
||||
/* When memory domain is used, the user must provide data buffers */
|
||||
(!opts->memory_domain || (iov && iov[0].iov_base));
|
||||
}
|
||||
|
||||
int
|
||||
spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
||||
struct iovec *iov, int iovcnt,
|
||||
@ -4299,11 +4317,7 @@ spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *
|
||||
void *md = NULL;
|
||||
|
||||
if (opts) {
|
||||
if (spdk_unlikely(!opts->size || opts->size > sizeof(struct spdk_bdev_ext_io_opts))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (spdk_unlikely(opts->memory_domain && !(iov && iov[0].iov_base))) {
|
||||
/* When memory domain is used, the user must provide data buffers */
|
||||
if (spdk_unlikely(!_bdev_io_check_opts(opts, iov))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
md = opts->metadata;
|
||||
@ -4441,20 +4455,7 @@ bdev_writev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *
|
||||
bdev_io->internal.ext_opts = opts;
|
||||
bdev_io->u.bdev.ext_opts = opts;
|
||||
|
||||
if (opts) {
|
||||
bool use_pull_push = opts->memory_domain && !desc->memory_domains_supported;
|
||||
|
||||
assert(opts->size <= sizeof(*opts));
|
||||
if (copy_opts || use_pull_push) {
|
||||
_bdev_io_copy_ext_opts(bdev_io, opts);
|
||||
if (use_pull_push) {
|
||||
_bdev_io_ext_use_bounce_buffer(bdev_io);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bdev_io_submit(bdev_io);
|
||||
_bdev_io_submit_ext(desc, bdev_io, opts, copy_opts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -4513,11 +4514,7 @@ spdk_bdev_writev_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel
|
||||
void *md = NULL;
|
||||
|
||||
if (opts) {
|
||||
if (spdk_unlikely(!opts->size || opts->size > sizeof(struct spdk_bdev_ext_io_opts))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (spdk_unlikely(opts->memory_domain && !(iov && iov[0].iov_base))) {
|
||||
/* When memory domain is used, the user must provide data buffers */
|
||||
if (spdk_unlikely(!_bdev_io_check_opts(opts, iov))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
md = opts->metadata;
|
||||
|
Loading…
Reference in New Issue
Block a user