Skip to content

Commit df069d8

Browse files
committed
io_uring: spin for sq thread to idle on shutdown
As part of io_uring shutdown, we cancel work that is pending and won't necessarily complete on its own. That includes requests like poll commands and timeouts. If we're using SQPOLL for kernel side submission and we shutdown the ring immediately after queueing such work, we can race with the sqthread doing the submission. This means we may miss cancelling some work, which results in the io_uring shutdown hanging forever. Cc: [email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 01d7a35 commit df069d8

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

fs/io_uring.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5070,7 +5070,8 @@ static int io_sq_thread(void *data)
50705070
* reap events and wake us up.
50715071
*/
50725072
if (inflight ||
5073-
(!time_after(jiffies, timeout) && ret != -EBUSY)) {
5073+
(!time_after(jiffies, timeout) && ret != -EBUSY &&
5074+
!percpu_ref_is_dying(&ctx->refs))) {
50745075
cond_resched();
50755076
continue;
50765077
}
@@ -6324,6 +6325,16 @@ static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx)
63246325
percpu_ref_kill(&ctx->refs);
63256326
mutex_unlock(&ctx->uring_lock);
63266327

6328+
/*
6329+
* Wait for sq thread to idle, if we have one. It won't spin on new
6330+
* work after we've killed the ctx ref above. This is important to do
6331+
* before we cancel existing commands, as the thread could otherwise
6332+
* be queueing new work post that. If that's work we need to cancel,
6333+
* it could cause shutdown to hang.
6334+
*/
6335+
while (ctx->sqo_thread && !wq_has_sleeper(&ctx->sqo_wait))
6336+
cpu_relax();
6337+
63276338
io_kill_timeouts(ctx);
63286339
io_poll_remove_all(ctx);
63296340

0 commit comments

Comments
 (0)