Skip to content

Commit

Permalink
io_uring/net: add IORING_ACCEPT_POLL_FIRST flag
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
axboe committed May 9, 2024
1 parent 7dcc758 commit d3da8e9
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/uapi/linux/io_uring.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ enum io_uring_op {
*/
#define IORING_ACCEPT_MULTISHOT (1U << 0)
#define IORING_ACCEPT_DONTWAIT (1U << 1)
#define IORING_ACCEPT_POLL_FIRST (1U << 2)

/*
* IORING_OP_MSG_RING command types, stored in sqe->addr
Expand Down
9 changes: 8 additions & 1 deletion io_uring/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit d3da8e9

Please sign in to comment.