| From df069d80c8e38c19531c392322e9a16617475c44 Mon Sep 17 00:00:00 2001 |
| From: Jens Axboe <axboe@kernel.dk> |
| Date: Tue, 4 Feb 2020 16:48:34 -0700 |
| Subject: io_uring: spin for sq thread to idle on shutdown |
| |
| From: Jens Axboe <axboe@kernel.dk> |
| |
| commit df069d80c8e38c19531c392322e9a16617475c44 upstream. |
| |
| 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: stable@vger.kernel.org |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/io_uring.c | 13 ++++++++++++- |
| 1 file changed, 12 insertions(+), 1 deletion(-) |
| |
| --- a/fs/io_uring.c |
| +++ b/fs/io_uring.c |
| @@ -3902,7 +3902,8 @@ static int io_sq_thread(void *data) |
| * reap events and wake us up. |
| */ |
| if (inflight || |
| - (!time_after(jiffies, timeout) && ret != -EBUSY)) { |
| + (!time_after(jiffies, timeout) && ret != -EBUSY && |
| + !percpu_ref_is_dying(&ctx->refs))) { |
| cond_resched(); |
| continue; |
| } |
| @@ -4983,6 +4984,16 @@ static void io_ring_ctx_wait_and_kill(st |
| percpu_ref_kill(&ctx->refs); |
| mutex_unlock(&ctx->uring_lock); |
| |
| + /* |
| + * Wait for sq thread to idle, if we have one. It won't spin on new |
| + * work after we've killed the ctx ref above. This is important to do |
| + * before we cancel existing commands, as the thread could otherwise |
| + * be queueing new work post that. If that's work we need to cancel, |
| + * it could cause shutdown to hang. |
| + */ |
| + while (ctx->sqo_thread && !wq_has_sleeper(&ctx->sqo_wait)) |
| + cpu_relax(); |
| + |
| io_kill_timeouts(ctx); |
| io_poll_remove_all(ctx); |
| |