diff options
author | Jens Axboe <axboe@kernel.dk> | 2022-11-25 19:36:29 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2022-11-25 20:55:08 +0300 |
commit | 7cfe7a09489c1cefee7181e07b5f2bcbaebd9f41 (patch) | |
tree | 2b7d696853a5ffdf093132952557e84286eff5d9 /io_uring | |
parent | 12ad3d2d6c5b0131a6052de91360849e3e154846 (diff) | |
download | linux-7cfe7a09489c1cefee7181e07b5f2bcbaebd9f41.tar.xz |
io_uring: clear TIF_NOTIFY_SIGNAL if set and task_work not available
With how task_work is added and signaled, we can have TIF_NOTIFY_SIGNAL
set and no task_work pending as it got run in a previous loop. Treat
TIF_NOTIFY_SIGNAL like get_signal(), always clear it if set regardless
of whether or not task_work is pending to run.
Cc: stable@vger.kernel.org
Fixes: 46a525e199e4 ("io_uring: don't gate task_work run on TIF_NOTIFY_SIGNAL")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring')
-rw-r--r-- | io_uring/io_uring.h | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h index cef5ff924e63..50bc3af44953 100644 --- a/io_uring/io_uring.h +++ b/io_uring/io_uring.h @@ -238,9 +238,14 @@ static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx) static inline int io_run_task_work(void) { + /* + * Always check-and-clear the task_work notification signal. With how + * signaling works for task_work, we can find it set with nothing to + * run. We need to clear it for that case, like get_signal() does. + */ + if (test_thread_flag(TIF_NOTIFY_SIGNAL)) + clear_notify_signal(); if (task_work_pending(current)) { - if (test_thread_flag(TIF_NOTIFY_SIGNAL)) - clear_notify_signal(); __set_current_state(TASK_RUNNING); task_work_run(); return 1; |