From df23d2dec286697dd73568faf142466e8067844a Mon Sep 17 00:00:00 2001
From: Roman Penyaev <rpenyaev@suse.de>
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 <rpenyaev@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 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