IORING_SETUP_SINGLE_ISSUER doesn't currently enable any optimizations, but it will soon be used to avoid taking io_ring_ctx's uring_lock when submitting from the single issuer task. If the IORING_SETUP_SQPOLL flag is set, the SQ thread is the sole task issuing SQEs. However, other tasks may make io_uring_register() syscalls, which must be synchronized with SQE submission. So it wouldn't be safe to skip the uring_lock around the SQ thread's submission even if IORING_SETUP_SINGLE_ISSUER is set. Therefore, clear IORING_SETUP_SINGLE_ISSUER from the io_ring_ctx flags if IORING_SETUP_SQPOLL is set. Signed-off-by: Caleb Sander Mateos --- io_uring/io_uring.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 42f6bfbb99d3..c7af9dc3d95a 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -3724,10 +3724,19 @@ static int io_uring_sanitise_params(struct io_uring_params *p) */ if ((flags & (IORING_SETUP_CQE32|IORING_SETUP_CQE_MIXED)) == (IORING_SETUP_CQE32|IORING_SETUP_CQE_MIXED)) return -EINVAL; + /* + * If IORING_SETUP_SQPOLL is set, only the SQ thread issues SQEs, + * but other threads may call io_uring_register() concurrently. + * We still need uring_lock to synchronize these io_ring_ctx accesses, + * so disable the single issuer optimizations. + */ + if (flags & IORING_SETUP_SQPOLL) + p->flags &= ~IORING_SETUP_SINGLE_ISSUER; + return 0; } int io_uring_fill_params(unsigned entries, struct io_uring_params *p) { -- 2.45.2