diff options
author | Jens Axboe <axboe@kernel.dk> | 2021-01-16 02:04:23 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2021-01-16 02:04:23 +0300 |
commit | a8d13dbccb137c46fead2ec1a4f1fbc8cfc9ea91 (patch) | |
tree | db70ccc1196e4b9a691f8a44d85ba7eb732c4b60 | |
parent | f010505b78a4fa8d5b6480752566e7313fb5ca6e (diff) | |
download | linux-a8d13dbccb137c46fead2ec1a4f1fbc8cfc9ea91.tar.xz |
io_uring: ensure finish_wait() is always called in __io_uring_task_cancel()
If we enter with requests pending and performm cancelations, we'll have
a different inflight count before and after calling prepare_to_wait().
This causes the loop to restart. If we actually ended up canceling
everything, or everything completed in-between, then we'll break out
of the loop without calling finish_wait() on the waitqueue. This can
trigger a warning on exit_signals(), as we leave the task state in
TASK_UNINTERRUPTIBLE.
Put a finish_wait() after the loop to catch that case.
Cc: stable@vger.kernel.org # 5.9+
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | fs/io_uring.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 06cc79d39586..985a9e3f976d 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -9101,6 +9101,7 @@ void __io_uring_task_cancel(void) finish_wait(&tctx->wait, &wait); } while (1); + finish_wait(&tctx->wait, &wait); atomic_dec(&tctx->in_idle); io_uring_remove_task_files(tctx); |