Change API to provide io_uring struct abstraction

This is cleaner than having the app juggle an SQ and CQ ring,
just wrap them in struct io_uring and have the API always take
that. This means the app doesn't need to worry about the different
types of rings, and that we only need to pass in one argument
for setup/teardown.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Jens Axboe
2019-01-08 15:31:35 -07:00
parent f47f24cea7
commit 7f7a66e385
3 changed files with 34 additions and 28 deletions

View File

@@ -42,19 +42,19 @@ static int __io_uring_get_completion(int fd, struct io_uring_cq *cq,
/* /*
* Return an IO completion, if one is readily available * Return an IO completion, if one is readily available
*/ */
int io_uring_get_completion(int fd, struct io_uring_cq *cq, int io_uring_get_completion(int fd, struct io_uring *ring,
struct io_uring_event **ev_ptr) struct io_uring_event **ev_ptr)
{ {
return __io_uring_get_completion(fd, cq, ev_ptr, 0); return __io_uring_get_completion(fd, &ring->cq, ev_ptr, 0);
} }
/* /*
* Return an IO completion, waiting for it if necessary * Return an IO completion, waiting for it if necessary
*/ */
int io_uring_wait_completion(int fd, struct io_uring_cq *cq, int io_uring_wait_completion(int fd, struct io_uring *ring,
struct io_uring_event **ev_ptr) struct io_uring_event **ev_ptr)
{ {
return __io_uring_get_completion(fd, cq, ev_ptr, 1); return __io_uring_get_completion(fd, &ring->cq, ev_ptr, 1);
} }
/* /*
@@ -62,8 +62,9 @@ int io_uring_wait_completion(int fd, struct io_uring_cq *cq,
* *
* Returns number of iocbs submitted * Returns number of iocbs submitted
*/ */
int io_uring_submit(int fd, struct io_uring_sq *sq) int io_uring_submit(int fd, struct io_uring *ring)
{ {
struct io_uring_sq *sq = &ring->sq;
const unsigned mask = *sq->kring_mask; const unsigned mask = *sq->kring_mask;
unsigned ktail, ktail_next, submitted; unsigned ktail, ktail_next, submitted;
@@ -117,8 +118,9 @@ submit:
* *
* Returns a vacant iocb, or NULL if we're full. * Returns a vacant iocb, or NULL if we're full.
*/ */
struct io_uring_iocb *io_uring_get_iocb(struct io_uring_sq *sq) struct io_uring_iocb *io_uring_get_iocb(struct io_uring *ring)
{ {
struct io_uring_sq *sq = &ring->sq;
unsigned next = sq->iocb_tail + 1; unsigned next = sq->iocb_tail + 1;
struct io_uring_iocb *iocb; struct io_uring_iocb *iocb;
@@ -186,8 +188,7 @@ err:
* contain the necessary information to read/write to the rings. * contain the necessary information to read/write to the rings.
*/ */
int io_uring_queue_init(unsigned entries, struct io_uring_params *p, int io_uring_queue_init(unsigned entries, struct io_uring_params *p,
struct iovec *iovecs, struct io_uring_sq *sq, struct iovec *iovecs, struct io_uring *ring)
struct io_uring_cq *cq)
{ {
int fd; int fd;
@@ -195,13 +196,15 @@ int io_uring_queue_init(unsigned entries, struct io_uring_params *p,
if (fd < 0) if (fd < 0)
return fd; return fd;
memset(sq, 0, sizeof(*sq)); memset(ring, 0, sizeof(*ring));
memset(cq, 0, sizeof(*cq)); return io_uring_mmap(fd, p, &ring->sq, &ring->cq);
return io_uring_mmap(fd, p, sq, cq);
} }
void io_uring_queue_exit(int fd, struct io_uring_sq *sq, struct io_uring_cq *cq) void io_uring_queue_exit(int fd, struct io_uring *ring)
{ {
struct io_uring_sq *sq = &ring->sq;
struct io_uring_cq *cq = &ring->cq;
munmap(sq->iocbs, *sq->kring_entries * sizeof(struct io_uring_iocb)); munmap(sq->iocbs, *sq->kring_entries * sizeof(struct io_uring_iocb));
munmap(sq->khead, sq->ring_sz); munmap(sq->khead, sq->ring_sz);
munmap(cq->khead, cq->ring_sz); munmap(cq->khead, cq->ring_sz);

View File

@@ -34,6 +34,11 @@ struct io_uring_cq {
size_t ring_sz; size_t ring_sz;
}; };
struct io_uring {
struct io_uring_sq sq;
struct io_uring_cq cq;
};
/* /*
* System calls * System calls
*/ */
@@ -46,20 +51,19 @@ extern int io_uring_enter(unsigned fd, unsigned to_submit,
* Library interface * Library interface
*/ */
extern int io_uring_queue_init(unsigned entries, struct io_uring_params *p, extern int io_uring_queue_init(unsigned entries, struct io_uring_params *p,
struct iovec *iovecs, struct io_uring_sq *sq, struct io_uring_cq *cq); struct iovec *iovecs, struct io_uring *ring);
extern void io_uring_queue_exit(int fd, struct io_uring_sq *sq, extern void io_uring_queue_exit(int fd, struct io_uring *ring);
struct io_uring_cq *cq); extern int io_uring_get_completion(int fd, struct io_uring *ring,
extern int io_uring_get_completion(int fd, struct io_uring_cq *cq,
struct io_uring_event **ev_ptr); struct io_uring_event **ev_ptr);
extern int io_uring_wait_completion(int fd, struct io_uring_cq *cq, extern int io_uring_wait_completion(int fd, struct io_uring *ring,
struct io_uring_event **ev_ptr); struct io_uring_event **ev_ptr);
extern int io_uring_submit(int fd, struct io_uring_sq *sq); extern int io_uring_submit(int fd, struct io_uring *ring);
extern struct io_uring_iocb *io_uring_get_iocb(struct io_uring_sq *sq); extern struct io_uring_iocb *io_uring_get_iocb(struct io_uring *ring);
static inline struct io_uring_iocb * static inline struct io_uring_iocb *
io_uring_iocb_from_ev(struct io_uring_sq *sq, struct io_uring_event *ev) io_uring_iocb_from_ev(struct io_uring *ring, struct io_uring_event *ev)
{ {
return &sq->iocbs[ev->index]; return &ring->sq.iocbs[ev->index];
} }
#endif #endif

View File

@@ -14,8 +14,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct io_uring_params p; struct io_uring_params p;
struct io_uring_sq sq; struct io_uring ring;
struct io_uring_cq cq;
int i, fd, ring_fd, ret, pending, done; int i, fd, ring_fd, ret, pending, done;
struct io_uring_iocb *iocb; struct io_uring_iocb *iocb;
struct io_uring_event *ev; struct io_uring_event *ev;
@@ -30,7 +29,7 @@ int main(int argc, char *argv[])
memset(&p, 0, sizeof(p)); memset(&p, 0, sizeof(p));
p.flags = IORING_SETUP_IOPOLL; p.flags = IORING_SETUP_IOPOLL;
ring_fd = io_uring_queue_init(4, &p, NULL, &sq, &cq); ring_fd = io_uring_queue_init(4, &p, NULL, &ring);
if (ring_fd < 0) { if (ring_fd < 0) {
fprintf(stderr, "queue_init: %s\n", strerror(-ring_fd)); fprintf(stderr, "queue_init: %s\n", strerror(-ring_fd));
return 1; return 1;
@@ -47,7 +46,7 @@ int main(int argc, char *argv[])
offset = 0; offset = 0;
do { do {
iocb = io_uring_get_iocb(&sq); iocb = io_uring_get_iocb(&ring);
if (!iocb) if (!iocb)
break; break;
iocb->opcode = IORING_OP_READ; iocb->opcode = IORING_OP_READ;
@@ -60,7 +59,7 @@ int main(int argc, char *argv[])
offset += 4096; offset += 4096;
} while (1); } while (1);
ret = io_uring_submit(ring_fd, &sq); ret = io_uring_submit(ring_fd, &ring);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "io_uring_submit: %s\n", strerror(-ret)); fprintf(stderr, "io_uring_submit: %s\n", strerror(-ret));
return 1; return 1;
@@ -70,7 +69,7 @@ int main(int argc, char *argv[])
pending = ret; pending = ret;
for (i = 0; i < pending; i++) { for (i = 0; i < pending; i++) {
ev = NULL; ev = NULL;
ret = io_uring_get_completion(ring_fd, &cq, &ev); ret = io_uring_get_completion(ring_fd, &ring, &ev);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "io_uring_get_completion: %s\n", strerror(-ret)); fprintf(stderr, "io_uring_get_completion: %s\n", strerror(-ret));
return 1; return 1;
@@ -85,6 +84,6 @@ int main(int argc, char *argv[])
printf("Submitted=%d, completed=%d\n", pending, done); printf("Submitted=%d, completed=%d\n", pending, done);
close(fd); close(fd);
io_uring_queue_exit(ring_fd, &sq, &cq); io_uring_queue_exit(ring_fd, &ring);
return 0; return 0;
} }