[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220203174108.668549-4-usama.arif@bytedance.com>
Date: Thu, 3 Feb 2022 17:41:08 +0000
From: Usama Arif <usama.arif@...edance.com>
To: io-uring@...r.kernel.org, axboe@...nel.dk, asml.silence@...il.com,
linux-kernel@...r.kernel.org
Cc: fam.zheng@...edance.com, Usama Arif <usama.arif@...edance.com>
Subject: [PATCH v3 3/3] io_uring: avoid ring quiesce for IORING_REGISTER_EVENTFD_ASYNC
This is done using the RCU data structure (io_ev_fd). eventfd_async
is moved from io_ring_ctx to io_ev_fd which is RCU protected hence
avoiding ring quiesce which is much more expensive than an RCU lock.
Signed-off-by: Usama Arif <usama.arif@...edance.com>
---
fs/io_uring.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 47d48020ae27..25ed86533910 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -328,6 +328,7 @@ struct io_submit_state {
struct io_ev_fd {
struct eventfd_ctx *cq_ev_fd;
+ unsigned int eventfd_async: 1;
};
struct io_ring_ctx {
@@ -339,7 +340,6 @@ struct io_ring_ctx {
unsigned int flags;
unsigned int compat: 1;
unsigned int drain_next: 1;
- unsigned int eventfd_async: 1;
unsigned int restricted: 1;
unsigned int off_timeout_used: 1;
unsigned int drain_active: 1;
@@ -1745,7 +1745,7 @@ static void io_eventfd_signal(struct io_ring_ctx *ctx)
if (READ_ONCE(ctx->rings->cq_flags) & IORING_CQ_EVENTFD_DISABLED)
goto out;
- if (!ctx->eventfd_async || io_wq_current_is_worker())
+ if (!ev_fd->eventfd_async || io_wq_current_is_worker())
eventfd_signal(ev_fd->cq_ev_fd, 1);
out:
@@ -9366,7 +9366,8 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
return done ? done : err;
}
-static int io_eventfd_register(struct io_ring_ctx *ctx, void __user *arg)
+static int io_eventfd_register(struct io_ring_ctx *ctx, void __user *arg,
+ unsigned int eventfd_async)
{
struct io_ev_fd *ev_fd;
__s32 __user *fds = arg;
@@ -9392,6 +9393,7 @@ static int io_eventfd_register(struct io_ring_ctx *ctx, void __user *arg)
kfree(ev_fd);
goto out;
}
+ ev_fd->eventfd_async = eventfd_async;
rcu_assign_pointer(ctx->io_ev_fd, ev_fd);
ret = 0;
@@ -11000,6 +11002,7 @@ static bool io_register_op_must_quiesce(int op)
case IORING_UNREGISTER_FILES:
case IORING_REGISTER_FILES_UPDATE:
case IORING_REGISTER_EVENTFD:
+ case IORING_REGISTER_EVENTFD_ASYNC:
case IORING_UNREGISTER_EVENTFD:
case IORING_REGISTER_PROBE:
case IORING_REGISTER_PERSONALITY:
@@ -11100,17 +11103,16 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
ret = io_register_files_update(ctx, arg, nr_args);
break;
case IORING_REGISTER_EVENTFD:
- case IORING_REGISTER_EVENTFD_ASYNC:
ret = -EINVAL;
if (nr_args != 1)
break;
- ret = io_eventfd_register(ctx, arg);
- if (ret)
+ ret = io_eventfd_register(ctx, arg, 0);
+ break;
+ case IORING_REGISTER_EVENTFD_ASYNC:
+ ret = -EINVAL;
+ if (nr_args != 1)
break;
- if (opcode == IORING_REGISTER_EVENTFD_ASYNC)
- ctx->eventfd_async = 1;
- else
- ctx->eventfd_async = 0;
+ ret = io_eventfd_register(ctx, arg, 1);
break;
case IORING_UNREGISTER_EVENTFD:
ret = -EINVAL;
--
2.25.1
Powered by blists - more mailing lists