From df23d2dec286697dd73568faf142466e8067844a Mon Sep 17 00:00:00 2001 From: Roman Penyaev Date: Mon, 27 May 2019 21:05:09 +0200 Subject: liburing,queue,setup: handle IORING_SQ_NEED_WAKEUP for io_uring_submit() Enter kernel only if SQ thread is off or wakeup is needed. Signed-off-by: Roman Penyaev Signed-off-by: Jens Axboe --- src/liburing.h | 1 + src/queue.c | 26 ++++++++++++++++++++++---- src/setup.c | 4 +++- 3 files changed, 26 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/liburing.h b/src/liburing.h index 2651b3d..ccefc40 100644 --- a/src/liburing.h +++ b/src/liburing.h @@ -46,6 +46,7 @@ struct io_uring_cq { struct io_uring { struct io_uring_sq sq; struct io_uring_cq cq; + unsigned flags; int ring_fd; }; diff --git a/src/queue.c b/src/queue.c index 5bbb279..eec26c9 100644 --- a/src/queue.c +++ b/src/queue.c @@ -62,6 +62,17 @@ int io_uring_wait_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr) return __io_uring_get_cqe(ring, cqe_ptr, 1); } +/* + * Returns true if we're not using SQ thread (thus nobody submits but us) + * or if IORING_SQ_NEED_WAKEUP is set, so dormouse should be explicitly + * awekened. + */ +static inline int sq_ring_needs_enter(struct io_uring *ring) +{ + return !(ring->flags & IORING_SETUP_SQPOLL) || + (*ring->sq.kflags & IORING_SQ_NEED_WAKEUP); +} + /* * Submit sqes acquired from io_uring_get_sqe() to the kernel. * @@ -125,10 +136,17 @@ int io_uring_submit(struct io_uring *ring) } submit: - ret = io_uring_enter(ring->ring_fd, submitted, 0, - IORING_ENTER_GETEVENTS, NULL); - if (ret < 0) - return -errno; + if (sq_ring_needs_enter(ring)) { + unsigned flags = 0; + + if ((*ring->sq.kflags & IORING_SQ_NEED_WAKEUP)) + flags |= IORING_ENTER_SQ_WAKEUP; + + ret = io_uring_enter(ring->ring_fd, submitted, 0, flags, NULL); + if (ret < 0) + return -errno; + } else + ret = submitted; return ret; } diff --git a/src/setup.c b/src/setup.c index 73f35de..9da3c19 100644 --- a/src/setup.c +++ b/src/setup.c @@ -69,8 +69,10 @@ int io_uring_queue_mmap(int fd, struct io_uring_params *p, struct io_uring *ring memset(ring, 0, sizeof(*ring)); ret = io_uring_mmap(fd, p, &ring->sq, &ring->cq); - if (!ret) + if (!ret) { + ring->flags = p->flags; ring->ring_fd = fd; + } return ret; } -- cgit