From: orkunsari Since commit 13d3783a55b7 ("io_uring: wait for in-flight requests on ring release"), the task dropping the last reference to a ring file waits in io_ring_ctx_wait_inflight() until every request on the ring has completed, and only a fatal signal ends the wait early. The requests may belong to other tasks and may not complete for an unbounded time, e.g. a read on a FUSE file whose server never replies. A process that merely received the ring fd over a UNIX socket and closes it then blocks in close(2) for as long as those requests stay in flight. The comment in io_ring_ctx_wait_and_kill() states that the wait is meant for requests owned by the task closing the ring. Only tasks that created or submitted to a ring have a node for it in their io_uring_task, so skip the wait for any other task and leave the remaining requests to io_ring_exit_work() as before. A thread of the same process that never attached to the ring no longer waits either when it drops the last reference. A task that is attached can still be held up by requests submitted by other tasks; that case is not addressed here. This was found by AI-assisted code review (Claude Code). The fix has been build-tested with W=1 only; no reproducer was run. Fixes: 13d3783a55b7 ("io_uring: wait for in-flight requests on ring release") Signed-off-by: orkunsari --- Regression in v7.4-rc1 only; released kernels are not affected. --- io_uring/io_uring.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 03724419c4..04e3da5de0 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -2547,7 +2547,16 @@ static __cold void io_ring_ctx_wait_inflight(struct io_ring_ctx *ctx) if (current->flags & (PF_KTHREAD | PF_EXITING)) return; - if (tctx && atomic_read(&tctx->in_cancel)) + /* + * Tasks that have attached to this ring (created it, submitted to it, + * registered its fd, ...) have a node for it in their io_uring_task. + * A task without one owns no requests here, e.g. one that received + * the fd over a socket, and must not be made to wait for requests it + * has no control over. + */ + if (!tctx || !xa_load(&tctx->xa, (unsigned long)ctx)) + return; + if (atomic_read(&tctx->in_cancel)) return; while (io_ring_ctx_inflight(ctx) && !fatal_signal_pending(current)) { --- base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4 change-id: 20261104-io-uring-wait-inflight-5ff78a7c6cd5 Best regards, -- orkunsari