Skip to content

Commit 7dcc758

Browse files
committed
io_uring/net: add IORING_ACCEPT_DONTWAIT flag
This allows the caller to perform a non-blocking attempt, similarly to how recvmsg has MSG_DONTWAIT. If set, and we get -EAGAIN on a connection attempt, propagate the result to userspace rather than arm poll and wait for a retry. Suggested-by: Norman Maurer <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 340f634 commit 7dcc758

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

include/uapi/linux/io_uring.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ enum io_uring_op {
379379
* accept flags stored in sqe->ioprio
380380
*/
381381
#define IORING_ACCEPT_MULTISHOT (1U << 0)
382+
#define IORING_ACCEPT_DONTWAIT (1U << 1)
382383

383384
/*
384385
* IORING_OP_MSG_RING command types, stored in sqe->addr

io_uring/net.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct io_accept {
2828
struct sockaddr __user *addr;
2929
int __user *addr_len;
3030
int flags;
31+
int iou_flags;
3132
u32 file_slot;
3233
unsigned long nofile;
3334
};
@@ -1489,7 +1490,6 @@ void io_sendrecv_fail(struct io_kiocb *req)
14891490
int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
14901491
{
14911492
struct io_accept *accept = io_kiocb_to_cmd(req, struct io_accept);
1492-
unsigned flags;
14931493

14941494
if (sqe->len || sqe->buf_index)
14951495
return -EINVAL;
@@ -1498,24 +1498,26 @@ int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
14981498
accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2));
14991499
accept->flags = READ_ONCE(sqe->accept_flags);
15001500
accept->nofile = rlimit(RLIMIT_NOFILE);
1501-
flags = READ_ONCE(sqe->ioprio);
1502-
if (flags & ~IORING_ACCEPT_MULTISHOT)
1501+
accept->iou_flags = READ_ONCE(sqe->ioprio);
1502+
if (accept->iou_flags & ~(IORING_ACCEPT_MULTISHOT | IORING_ACCEPT_DONTWAIT))
15031503
return -EINVAL;
15041504

15051505
accept->file_slot = READ_ONCE(sqe->file_index);
15061506
if (accept->file_slot) {
15071507
if (accept->flags & SOCK_CLOEXEC)
15081508
return -EINVAL;
1509-
if (flags & IORING_ACCEPT_MULTISHOT &&
1509+
if (accept->iou_flags & IORING_ACCEPT_MULTISHOT &&
15101510
accept->file_slot != IORING_FILE_INDEX_ALLOC)
15111511
return -EINVAL;
15121512
}
15131513
if (accept->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
15141514
return -EINVAL;
15151515
if (SOCK_NONBLOCK != O_NONBLOCK && (accept->flags & SOCK_NONBLOCK))
15161516
accept->flags = (accept->flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1517-
if (flags & IORING_ACCEPT_MULTISHOT)
1517+
if (accept->iou_flags & IORING_ACCEPT_MULTISHOT)
15181518
req->flags |= REQ_F_APOLL_MULTISHOT;
1519+
if (accept->iou_flags & IORING_ACCEPT_DONTWAIT)
1520+
req->flags |= REQ_F_NOWAIT;
15191521
return 0;
15201522
}
15211523

@@ -1540,7 +1542,8 @@ int io_accept(struct io_kiocb *req, unsigned int issue_flags)
15401542
if (!fixed)
15411543
put_unused_fd(fd);
15421544
ret = PTR_ERR(file);
1543-
if (ret == -EAGAIN && force_nonblock) {
1545+
if (ret == -EAGAIN && force_nonblock &&
1546+
!(accept->iou_flags & IORING_ACCEPT_DONTWAIT)) {
15441547
/*
15451548
* if it's multishot and polled, we don't need to
15461549
* return EAGAIN to arm the poll infra since it

0 commit comments

Comments
 (0)