Skip to content

Commit 1ceaf63

Browse files
riteshharjaniaxboe
authored andcommitted
libaio: Add vectored io support
This adds support for doing vectored I/O to libaio. Instead of using pread/pwrite calls, this allows libaio to use preadv/pwritev calls which uses iovecs. option: libaio_vectored=1 Signed-off-by: Ritesh Harjani (IBM) <[email protected]> Link: https://lore.kernel.org/r/f0d66512e3df3d2142910e996c42389c21232d12.1739608655.git.ritesh.list@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent 2768c33 commit 1ceaf63

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

HOWTO.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,10 @@ with the caveat that when used on the command line, they must come after the
25152515
not support torn-write protection. To learn a file's torn-write limits, issue
25162516
statx with STATX_WRITE_ATOMIC.
25172517

2518+
.. option:: libaio_vectored=bool : [libaio]
2519+
2520+
Submit vectored read and write requests.
2521+
25182522
.. option:: fdp=bool : [io_uring_cmd] [xnvme]
25192523

25202524
Enable Flexible Data Placement mode for write commands.

engines/libaio.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct libaio_data {
3737
struct io_u **io_us;
3838

3939
struct io_u **io_u_index;
40+
struct iovec *iovecs; /* for vectored requests */
4041

4142
/*
4243
* Basic ring buffer. 'head' is incremented in _queue(), and
@@ -60,6 +61,7 @@ struct libaio_options {
6061
unsigned int userspace_reap;
6162
struct cmdprio_options cmdprio_options;
6263
unsigned int nowait;
64+
unsigned int vectored;
6365
};
6466

6567
static struct fio_option options[] = {
@@ -81,6 +83,16 @@ static struct fio_option options[] = {
8183
.category = FIO_OPT_C_ENGINE,
8284
.group = FIO_OPT_G_LIBAIO,
8385
},
86+
{
87+
.name = "libaio_vectored",
88+
.lname = "Use libaio preadv,pwritev",
89+
.type = FIO_OPT_BOOL,
90+
.off1 = offsetof(struct libaio_options, vectored),
91+
.help = "Use libaio {preadv,pwritev} instead of libaio {pread,pwrite}",
92+
.category = FIO_OPT_C_ENGINE,
93+
.group = FIO_OPT_G_LIBAIO,
94+
},
95+
8496
CMDPRIO_OPTIONS(struct libaio_options, FIO_OPT_G_LIBAIO),
8597
{
8698
.name = NULL,
@@ -101,13 +113,32 @@ static int fio_libaio_prep(struct thread_data *td, struct io_u *io_u)
101113
struct libaio_options *o = td->eo;
102114
struct fio_file *f = io_u->file;
103115
struct iocb *iocb = &io_u->iocb;
116+
struct libaio_data *ld = td->io_ops_data;
104117

105118
if (io_u->ddir == DDIR_READ) {
106-
io_prep_pread(iocb, f->fd, io_u->xfer_buf, io_u->xfer_buflen, io_u->offset);
119+
if (o->vectored) {
120+
struct iovec *iov = &ld->iovecs[io_u->index];
121+
122+
iov->iov_base = io_u->xfer_buf;
123+
iov->iov_len = (size_t)io_u->xfer_buflen;
124+
io_prep_preadv(iocb, f->fd, iov, 1, io_u->offset);
125+
} else {
126+
io_prep_pread(iocb, f->fd, io_u->xfer_buf, io_u->xfer_buflen,
127+
io_u->offset);
128+
}
107129
if (o->nowait)
108130
iocb->aio_rw_flags |= RWF_NOWAIT;
109131
} else if (io_u->ddir == DDIR_WRITE) {
110-
io_prep_pwrite(iocb, f->fd, io_u->xfer_buf, io_u->xfer_buflen, io_u->offset);
132+
if (o->vectored) {
133+
struct iovec *iov = &ld->iovecs[io_u->index];
134+
135+
iov->iov_base = io_u->xfer_buf;
136+
iov->iov_len = (size_t)io_u->xfer_buflen;
137+
io_prep_pwritev(iocb, f->fd, iov, 1, io_u->offset);
138+
} else {
139+
io_prep_pwrite(iocb, f->fd, io_u->xfer_buf, io_u->xfer_buflen,
140+
io_u->offset);
141+
}
111142
if (o->nowait)
112143
iocb->aio_rw_flags |= RWF_NOWAIT;
113144
#ifdef FIO_HAVE_RWF_ATOMIC
@@ -394,6 +425,7 @@ static void fio_libaio_cleanup(struct thread_data *td)
394425
io_destroy(ld->aio_ctx);
395426

396427
fio_cmdprio_cleanup(&ld->cmdprio);
428+
free(ld->iovecs);
397429
free(ld->aio_events);
398430
free(ld->iocbs);
399431
free(ld->io_us);
@@ -428,6 +460,7 @@ static int fio_libaio_init(struct thread_data *td)
428460
ld->aio_events = calloc(ld->entries, sizeof(struct io_event));
429461
ld->iocbs = calloc(ld->entries, sizeof(struct iocb *));
430462
ld->io_us = calloc(ld->entries, sizeof(struct io_u *));
463+
ld->iovecs = calloc(ld->entries, sizeof(ld->iovecs[0]));
431464

432465
td->io_ops_data = ld;
433466

0 commit comments

Comments
 (0)