diff options
author | Dylan Yudaken <dylany@fb.com> | 2022-03-25 10:37:55 +0100 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2022-03-25 13:30:23 +0100 |
commit | 52dd86406dfa322c8d42b3a4328858abdc6f1d85 (patch) | |
tree | 401c67c36d89fd07932342b741a74d1c745dc933 /fs | |
parent | io_uring: improve task work cache utilization (diff) | |
download | linux-52dd86406dfa322c8d42b3a4328858abdc6f1d85.tar.xz linux-52dd86406dfa322c8d42b3a4328858abdc6f1d85.zip |
io_uring: enable EPOLLEXCLUSIVE for accept poll
When polling sockets for accept, use EPOLLEXCLUSIVE. This is helpful
when multiple accept SQEs are submitted.
For O_NONBLOCK sockets multiple queued SQEs would previously have all
completed at once, but most with -EAGAIN as the result. Now only one
wakes up and completes.
For sockets without O_NONBLOCK there is no user facing change, but
internally the extra requests would previously be queued onto a worker
thread as they would wake up with no connection waiting, and be
punted. Now they do not wake up unnecessarily.
Co-developed-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Dylan Yudaken <dylany@fb.com>
Link: https://lore.kernel.org/r/20220325093755.4123343-1-dylany@fb.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/io_uring.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index bb40c80fd9ca..e72f58e2d06d 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -967,6 +967,7 @@ struct io_op_def { /* set if opcode supports polled "wait" */ unsigned pollin : 1; unsigned pollout : 1; + unsigned poll_exclusive : 1; /* op supports buffer selection */ unsigned buffer_select : 1; /* do prep async if is going to be punted */ @@ -1061,6 +1062,7 @@ static const struct io_op_def io_op_defs[] = { .needs_file = 1, .unbound_nonreg_file = 1, .pollin = 1, + .poll_exclusive = 1, }, [IORING_OP_ASYNC_CANCEL] = { .audit_skip = 1, @@ -6280,7 +6282,8 @@ static int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags) } else { mask |= POLLOUT | POLLWRNORM; } - + if (def->poll_exclusive) + mask |= EPOLLEXCLUSIVE; if (!(issue_flags & IO_URING_F_UNLOCKED) && !list_empty(&ctx->apoll_cache)) { apoll = list_first_entry(&ctx->apoll_cache, struct async_poll, |