diff options
author | Jens Axboe <axboe@kernel.dk> | 2024-05-08 08:17:50 -0600 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2024-05-09 12:22:11 -0600 |
commit | d3da8e98592693811c14c31f05380f378411fea1 (patch) | |
tree | 885a341cad3532350cdab6c841a78c8d20425805 /io_uring | |
parent | 7dcc758cca432510f77b2fe1077be2314bc3785b (diff) | |
download | linux-d3da8e98592693811c14c31f05380f378411fea1.tar.gz linux-d3da8e98592693811c14c31f05380f378411fea1.tar.bz2 linux-d3da8e98592693811c14c31f05380f378411fea1.zip |
io_uring/net: add IORING_ACCEPT_POLL_FIRST flag
Similarly to how polling first is supported for receive, it makes sense
to provide the same for accept. An accept operation does a lot of
expensive setup, like allocating an fd, a socket/inode, etc. If no
connection request is already pending, this is wasted and will just be
cleaned up and freed, only to retry via the usual poll trigger.
Add IORING_ACCEPT_POLL_FIRST, which tells accept to only initiate the
accept request if poll says we have something to accept.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring')
-rw-r--r-- | io_uring/net.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/io_uring/net.c b/io_uring/net.c index 7861bc8fe8b1..070dea9a4eda 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -1487,6 +1487,9 @@ void io_sendrecv_fail(struct io_kiocb *req) req->cqe.flags |= IORING_CQE_F_MORE; } +#define ACCEPT_FLAGS (IORING_ACCEPT_MULTISHOT | IORING_ACCEPT_DONTWAIT | \ + IORING_ACCEPT_POLL_FIRST) + int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_accept *accept = io_kiocb_to_cmd(req, struct io_accept); @@ -1499,7 +1502,7 @@ int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) accept->flags = READ_ONCE(sqe->accept_flags); accept->nofile = rlimit(RLIMIT_NOFILE); accept->iou_flags = READ_ONCE(sqe->ioprio); - if (accept->iou_flags & ~(IORING_ACCEPT_MULTISHOT | IORING_ACCEPT_DONTWAIT)) + if (accept->iou_flags & ~ACCEPT_FLAGS) return -EINVAL; accept->file_slot = READ_ONCE(sqe->file_index); @@ -1530,6 +1533,10 @@ int io_accept(struct io_kiocb *req, unsigned int issue_flags) struct file *file; int ret, fd; + if (!(req->flags & REQ_F_POLLED) && + accept->iou_flags & IORING_ACCEPT_POLL_FIRST) + return -EAGAIN; + retry: if (!fixed) { fd = __get_unused_fd_flags(accept->flags, accept->nofile); |