From 6cdce17753a3664484c907ed264e734ed5f3c2d7 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 10 Jan 2019 09:32:41 -0700 Subject: Update API - io_uring_sqe added a data field that's passed back at completion - io_uring_sqe added an index field, for fixed buffer locations - io_uring_setup(2) system call added a 'nr_iovecs' field Signed-off-by: Jens Axboe --- src/io_uring.c | 5 +++-- src/io_uring.h | 19 +++++++++++-------- src/liburing.h | 10 ++-------- src/syscall.c | 4 ++-- test/io_uring-cp.c | 30 +++++++++++++++++++++--------- test/io_uring-test.c | 2 +- 6 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/io_uring.c b/src/io_uring.c index 6168b56..d9c1511 100644 --- a/src/io_uring.c +++ b/src/io_uring.c @@ -189,11 +189,12 @@ err: * contains the necessary information to read/write to the rings. */ int io_uring_queue_init(unsigned entries, struct io_uring_params *p, - struct iovec *iovecs, struct io_uring *ring) + struct iovec *iovecs, unsigned nr_iovecs, + struct io_uring *ring) { int fd, ret; - fd = io_uring_setup(entries, iovecs, p); + fd = io_uring_setup(entries, iovecs, nr_iovecs, p); if (fd < 0) return fd; diff --git a/src/io_uring.h b/src/io_uring.h index 20e4c22..b07bbbb 100644 --- a/src/io_uring.h +++ b/src/io_uring.h @@ -15,20 +15,23 @@ * IO submission data structure (Submission Queue Entry) */ struct io_uring_sqe { - __u8 opcode; - __u8 flags; - __u16 ioprio; - __s32 fd; - __u64 off; + __u8 opcode; /* type of operation for this sqe */ + __u8 flags; /* as of now unused */ + __u16 ioprio; /* ioprio for the request */ + __s32 fd; /* file descriptor to do IO on */ + __u64 off; /* offset into file */ union { - void *addr; + void *addr; /* buffer or iovecs */ __u64 __pad; }; - __u32 len; + __u32 len; /* buffer size or number of iovecs */ union { __kernel_rwf_t rw_flags; __u32 __resv; }; + __u16 index; /* index into fixed buffers, if used */ + __u16 __pad2[3]; + __u64 data; /* data to be passed back at completion time */ }; /* @@ -50,7 +53,7 @@ struct io_uring_sqe { * IO completion data structure (Completion Queue Entry) */ struct io_uring_cqe { - __u64 index; /* what sqe this event came from */ + __u64 data; /* sqe->data submission passed back */ __s32 res; /* result code for this event */ __u32 flags; }; diff --git a/src/liburing.h b/src/liburing.h index 8adc9ec..ac645f1 100644 --- a/src/liburing.h +++ b/src/liburing.h @@ -44,7 +44,7 @@ struct io_uring { * System calls */ extern int io_uring_setup(unsigned entries, struct iovec *iovecs, - struct io_uring_params *p); + unsigned nr_iovecs, struct io_uring_params *p); extern int io_uring_enter(unsigned fd, unsigned to_submit, unsigned min_complete, unsigned flags); @@ -52,7 +52,7 @@ extern int io_uring_enter(unsigned fd, unsigned to_submit, * Library interface */ extern int io_uring_queue_init(unsigned entries, struct io_uring_params *p, - struct iovec *iovecs, struct io_uring *ring); + struct iovec *iovecs, unsigned nr_iovecs, struct io_uring *ring); extern void io_uring_queue_exit(struct io_uring *ring); extern int io_uring_get_completion(struct io_uring *ring, struct io_uring_cqe **cqe_ptr); @@ -61,10 +61,4 @@ extern int io_uring_wait_completion(struct io_uring *ring, extern int io_uring_submit(struct io_uring *ring); extern struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring); -static inline struct io_uring_sqe * -io_uring_sqe_from_cqe(struct io_uring *ring, struct io_uring_cqe *cqe) -{ - return &ring->sq.sqes[cqe->index]; -} - #endif diff --git a/src/syscall.c b/src/syscall.c index eafdd39..d06d59c 100644 --- a/src/syscall.c +++ b/src/syscall.c @@ -18,9 +18,9 @@ #endif int io_uring_setup(unsigned int entries, struct iovec *iovecs, - struct io_uring_params *p) + unsigned nr_iovecs, struct io_uring_params *p) { - return syscall(__NR_sys_io_uring_setup, entries, iovecs, p); + return syscall(__NR_sys_io_uring_setup, entries, iovecs, nr_iovecs, p); } int io_uring_enter(int fd, unsigned int to_submit, unsigned int min_complete, diff --git a/test/io_uring-cp.c b/test/io_uring-cp.c index 176d9de..9d7c56c 100644 --- a/test/io_uring-cp.c +++ b/test/io_uring-cp.c @@ -18,6 +18,11 @@ static struct io_uring in_ring; static struct io_uring out_ring; static struct iovec iovecs[QD]; +struct io_data { + off_t offset; + struct iovec *iov; +}; + static int setup_context(unsigned entries, struct io_uring *ring, int offload) { struct io_uring_params p; @@ -27,7 +32,7 @@ static int setup_context(unsigned entries, struct io_uring *ring, int offload) if (offload) p.flags = IORING_SETUP_SQWQ; - ret = io_uring_queue_init(entries, &p, NULL, ring); + ret = io_uring_queue_init(entries, &p, NULL, 0, ring); if (ret < 0) { fprintf(stderr, "queue_init: %s\n", strerror(-ret)); return -1; @@ -58,17 +63,23 @@ static unsigned sqe_index(struct io_uring_sqe *sqe) static int queue_read(int fd, off_t size, off_t offset) { struct io_uring_sqe *sqe; + struct io_data *data; sqe = io_uring_get_sqe(&in_ring); if (!sqe) return 1; + data = malloc(sizeof(*data)); + data->offset = offset; + data->iov = &iovecs[sqe_index(sqe)]; + sqe->opcode = IORING_OP_READV; sqe->flags = 0; sqe->ioprio = 0; sqe->fd = fd; sqe->off = offset; - sqe->addr = &iovecs[sqe_index(sqe)]; + sqe->addr = data->iov; + sqe->data = (unsigned long) data; iovecs[sqe_index(sqe)].iov_len = size; sqe->len = 1; return 0; @@ -105,8 +116,9 @@ static int complete_writes(unsigned *writes) return 0; } -static void queue_write(int fd, off_t size, off_t offset, unsigned index) +static void queue_write(int fd, struct io_uring_cqe *cqe) { + struct io_data *data = (struct io_data *) cqe->data; struct io_uring_sqe *sqe; sqe = io_uring_get_sqe(&out_ring); @@ -114,10 +126,12 @@ static void queue_write(int fd, off_t size, off_t offset, unsigned index) sqe->flags = 0; sqe->ioprio = 0; sqe->fd = fd; - sqe->off = offset; - sqe->addr = &iovecs[index]; - iovecs[index].iov_len = size; + sqe->off = data->offset; + sqe->addr = data->iov; + sqe->data = 0; + data->iov->iov_len = cqe->res; sqe->len = 1; + free(data); } int main(int argc, char *argv[]) @@ -164,7 +178,6 @@ int main(int argc, char *argv[]) write_left = read_left; while (read_left || write_left) { off_t this_size = read_left; - struct io_uring_sqe *sqe; if (this_size > BS) this_size = BS; @@ -209,8 +222,7 @@ skip_read: strerror(-cqe->res)); return 1; } - sqe = io_uring_sqe_from_cqe(&in_ring, cqe); - queue_write(outfd, cqe->res, sqe->off, cqe->index); + queue_write(outfd, cqe); write_left -= cqe->res; writes++; }; diff --git a/test/io_uring-test.c b/test/io_uring-test.c index aaf7e66..caf61ed 100644 --- a/test/io_uring-test.c +++ b/test/io_uring-test.c @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) memset(&p, 0, sizeof(p)); p.flags = IORING_SETUP_IOPOLL; - ret = io_uring_queue_init(QD, &p, NULL, &ring); + ret = io_uring_queue_init(QD, &p, NULL, 0, &ring); if (ret < 0) { fprintf(stderr, "queue_init: %s\n", strerror(-ret)); return 1; -- cgit