spdk_dd: Add app parameter to force AIO usage

Signed-off-by: Maciej Szwed <maciej.szwed@intel.com>
Change-Id: I6ac4dfcd7c17b4e3c23830b642a0534e3541af6e
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3474
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Maciej Szwed 2020-07-22 09:13:27 +02:00 committed by Tomasz Zawadzki
parent 0b280d5887
commit 6bb13965a5

View File

@ -60,6 +60,7 @@ struct spdk_dd_opts {
int64_t io_unit_size;
int64_t io_unit_count;
uint32_t queue_depth;
bool aio;
};
static struct spdk_dd_opts g_opts = {
@ -105,13 +106,12 @@ struct dd_target {
struct io_uring ring;
struct spdk_poller *poller;
} uring;
#else
#endif
struct {
int fd;
io_context_t io_ctx;
struct spdk_poller *poller;
} aio;
#endif
} u;
/* Block size of underlying device. */
@ -166,13 +166,16 @@ dd_exit(int rc)
{
if (g_job.input.type == DD_TARGET_TYPE_FILE) {
#ifdef SPDK_CONFIG_URING
spdk_poller_unregister(&g_job.input.u.uring.poller);
close(g_job.input.u.uring.fd);
#else
spdk_poller_unregister(&g_job.input.u.aio.poller);
io_destroy(g_job.input.u.aio.io_ctx);
close(g_job.input.u.aio.fd);
if (g_opts.aio == false) {
spdk_poller_unregister(&g_job.input.u.uring.poller);
close(g_job.input.u.uring.fd);
} else
#endif
{
spdk_poller_unregister(&g_job.input.u.aio.poller);
io_destroy(g_job.input.u.aio.io_ctx);
close(g_job.input.u.aio.fd);
}
} else if (g_job.input.type == DD_TARGET_TYPE_BDEV && g_job.input.open) {
spdk_put_io_channel(g_job.input.u.bdev.ch);
spdk_bdev_close(g_job.input.u.bdev.desc);
@ -180,13 +183,16 @@ dd_exit(int rc)
if (g_job.output.type == DD_TARGET_TYPE_FILE) {
#ifdef SPDK_CONFIG_URING
spdk_poller_unregister(&g_job.output.u.uring.poller);
close(g_job.output.u.uring.fd);
#else
spdk_poller_unregister(&g_job.output.u.aio.poller);
io_destroy(g_job.output.u.aio.io_ctx);
close(g_job.output.u.aio.fd);
if (g_opts.aio == false) {
spdk_poller_unregister(&g_job.output.u.uring.poller);
close(g_job.output.u.uring.fd);
} else
#endif
{
spdk_poller_unregister(&g_job.output.u.aio.poller);
io_destroy(g_job.output.u.aio.io_ctx);
close(g_job.output.u.aio.fd);
}
} else if (g_job.output.type == DD_TARGET_TYPE_BDEV && g_job.output.open) {
spdk_put_io_channel(g_job.output.u.bdev.ch);
spdk_bdev_close(g_job.output.u.bdev.desc);
@ -320,16 +326,19 @@ dd_target_write(struct dd_io *io)
if (target->type == DD_TARGET_TYPE_FILE) {
#ifdef SPDK_CONFIG_URING
dd_uring_submit(io, target, length, write_offset);
#else
struct iocb *iocb = &io->iocb;
io_prep_pwrite(iocb, target->u.aio.fd, io->buf, length, write_offset);
iocb->data = io;
if (io_submit(target->u.aio.io_ctx, 1, &iocb) < 0) {
rc = -errno;
}
if (g_opts.aio == false) {
dd_uring_submit(io, target, length, write_offset);
} else
#endif
{
struct iocb *iocb = &io->iocb;
io_prep_pwrite(iocb, target->u.aio.fd, io->buf, length, write_offset);
iocb->data = io;
if (io_submit(target->u.aio.io_ctx, 1, &iocb) < 0) {
rc = -errno;
}
}
} else if (target->type == DD_TARGET_TYPE_BDEV) {
rc = spdk_bdev_write(target->u.bdev.desc, target->u.bdev.ch, io->buf, write_offset, length,
_dd_write_bdev_done, io);
@ -379,16 +388,19 @@ dd_target_read(struct dd_io *io)
if (target->type == DD_TARGET_TYPE_FILE) {
#ifdef SPDK_CONFIG_URING
dd_uring_submit(io, target, io->length, io->offset);
#else
struct iocb *iocb = &io->iocb;
io_prep_pread(iocb, target->u.aio.fd, io->buf, io->length, io->offset);
iocb->data = io;
if (io_submit(target->u.aio.io_ctx, 1, &iocb) < 0) {
rc = -errno;
}
if (g_opts.aio == false) {
dd_uring_submit(io, target, io->length, io->offset);
} else
#endif
{
struct iocb *iocb = &io->iocb;
io_prep_pread(iocb, target->u.aio.fd, io->buf, io->length, io->offset);
iocb->data = io;
if (io_submit(target->u.aio.io_ctx, 1, &iocb) < 0) {
rc = -errno;
}
}
} else if (target->type == DD_TARGET_TYPE_BDEV) {
rc = spdk_bdev_read(target->u.bdev.desc, target->u.bdev.ch, io->buf, io->offset, io->length,
_dd_read_bdev_done, io);
@ -459,16 +471,19 @@ dd_target_populate_buffer(struct dd_io *io)
if (target->type == DD_TARGET_TYPE_FILE) {
#ifdef SPDK_CONFIG_URING
dd_uring_submit(io, target, length, write_offset);
#else
struct iocb *iocb = &io->iocb;
io_prep_pread(iocb, target->u.aio.fd, io->buf, length, write_offset);
iocb->data = io;
if (io_submit(target->u.aio.io_ctx, 1, &iocb) < 0) {
rc = -errno;
}
if (g_opts.aio == false) {
dd_uring_submit(io, target, length, write_offset);
} else
#endif
{
struct iocb *iocb = &io->iocb;
io_prep_pread(iocb, target->u.aio.fd, io->buf, length, write_offset);
iocb->data = io;
if (io_submit(target->u.aio.io_ctx, 1, &iocb) < 0) {
rc = -errno;
}
}
} else if (target->type == DD_TARGET_TYPE_BDEV) {
rc = spdk_bdev_read(target->u.bdev.desc, target->u.bdev.ch, io->buf, write_offset, length,
_dd_target_populate_buffer_done, io);
@ -540,8 +555,7 @@ dd_uring_poll(void *ctx)
return rc;
}
#else
#endif
static int
dd_aio_poll(io_context_t io_ctx)
@ -603,17 +617,21 @@ dd_output_poll(void *ctx)
return rc;
}
#endif
static int
dd_open_file(struct dd_target *target, const char *fname, int flags, uint64_t skip_blocks,
bool input)
{
int *fd;
#ifdef SPDK_CONFIG_URING
int *fd = &target->u.uring.fd;
#else
int *fd = &target->u.aio.fd;
if (g_opts.aio == false) {
fd = &target->u.uring.fd;
} else
#endif
{
fd = &target->u.aio.fd;
}
flags |= O_RDWR;
@ -627,7 +645,7 @@ dd_open_file(struct dd_target *target, const char *fname, int flags, uint64_t sk
#ifdef SPDK_CONFIG_URING
/* io_uring does not work correctly with O_NONBLOCK flag */
if (flags & O_NONBLOCK) {
if (flags & O_NONBLOCK && g_opts.aio == false) {
flags &= ~O_NONBLOCK;
SPDK_WARNLOG("Skipping 'nonblock' flag due to existing issue with uring implementation and this flag\n");
}
@ -653,12 +671,15 @@ dd_open_file(struct dd_target *target, const char *fname, int flags, uint64_t sk
}
#ifdef SPDK_CONFIG_URING
io_uring_queue_init(g_opts.queue_depth, &target->u.uring.ring, 0);
target->open = true;
return 0;
#else
return io_setup(g_opts.queue_depth, &target->u.aio.io_ctx);
if (g_opts.aio == false) {
io_uring_queue_init(g_opts.queue_depth, &target->u.uring.ring, 0);
target->open = true;
return 0;
} else
#endif
{
return io_setup(g_opts.queue_depth, &target->u.aio.io_ctx);
}
}
static int
@ -754,10 +775,13 @@ dd_run(void *arg1)
return;
}
#ifdef SPDK_CONFIG_URING
g_job.input.u.uring.poller = spdk_poller_register(dd_uring_poll, &g_job.input, 0);
#else
g_job.input.u.aio.poller = spdk_poller_register(dd_input_poll, NULL, 0);
if (g_opts.aio == false) {
g_job.input.u.uring.poller = spdk_poller_register(dd_uring_poll, &g_job.input, 0);
} else
#endif
{
g_job.input.u.aio.poller = spdk_poller_register(dd_input_poll, NULL, 0);
}
} else if (g_opts.input_bdev) {
rc = dd_open_bdev(&g_job.input, g_opts.input_bdev, g_opts.input_offset);
if (rc < 0) {
@ -808,10 +832,13 @@ dd_run(void *arg1)
return;
}
#ifdef SPDK_CONFIG_URING
g_job.output.u.uring.poller = spdk_poller_register(dd_uring_poll, &g_job.output, 0);
#else
g_job.output.u.aio.poller = spdk_poller_register(dd_output_poll, NULL, 0);
if (g_opts.aio == false) {
g_job.output.u.uring.poller = spdk_poller_register(dd_uring_poll, &g_job.output, 0);
} else
#endif
{
g_job.output.u.aio.poller = spdk_poller_register(dd_output_poll, NULL, 0);
}
} else if (g_opts.output_bdev) {
rc = dd_open_bdev(&g_job.output, g_opts.output_bdev, g_opts.output_offset);
if (rc < 0) {
@ -879,6 +906,7 @@ enum dd_cmdline_opts {
DD_OPTION_BS,
DD_OPTION_QD,
DD_OPTION_COUNT,
DD_OPTION_AIO,
};
static struct option g_cmdline_opts[] = {
@ -948,6 +976,12 @@ static struct option g_cmdline_opts[] = {
.flag = NULL,
.val = DD_OPTION_COUNT,
},
{
.name = "aio",
.has_arg = 0,
.flag = NULL,
.val = DD_OPTION_AIO,
},
{
.name = NULL
}
@ -968,6 +1002,7 @@ usage(void)
printf(" --count I/O unit count. The number of I/O units to copy. (default: all)\n");
printf(" --skip Skip this many I/O units at start of input. (default: 0)\n");
printf(" --seek Skip this many I/O units at start of output. (default: 0)\n");
printf(" --aio Force usage of AIO. (by default io_uring is used if available)\n");
printf(" Available iflag and oflag values:\n");
printf(" append - append mode\n");
printf(" direct - use direct I/O for data\n");
@ -1017,6 +1052,9 @@ parse_args(int argc, char *argv)
case DD_OPTION_COUNT:
g_opts.io_unit_count = spdk_strtol(optarg, 10);
break;
case DD_OPTION_AIO:
g_opts.aio = true;
break;
default:
usage();
return 1;
@ -1037,12 +1075,14 @@ dd_free(void)
free(g_opts.output_file_flags);
#ifdef SPDK_CONFIG_URING
if (g_job.input.type == DD_TARGET_TYPE_FILE && g_job.input.open == true) {
io_uring_queue_exit(&g_job.input.u.uring.ring);
}
if (g_opts.aio == false) {
if (g_job.input.type == DD_TARGET_TYPE_FILE && g_job.input.open == true) {
io_uring_queue_exit(&g_job.input.u.uring.ring);
}
if (g_job.output.type == DD_TARGET_TYPE_FILE && g_job.output.open == true) {
io_uring_queue_exit(&g_job.output.u.uring.ring);
if (g_job.output.type == DD_TARGET_TYPE_FILE && g_job.output.open == true) {
io_uring_queue_exit(&g_job.output.u.uring.ring);
}
}
#endif