Commit 52dd8640 authored by Dylan Yudaken's avatar Dylan Yudaken Committed by Jens Axboe
Browse files

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: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarDylan Yudaken <dylany@fb.com>
Link: https://lore.kernel.org/r/20220325093755.4123343-1-dylany@fb.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 34d2bfe7
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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,