• Nadav Amit's avatar
    io_uring: clear TIF_NOTIFY_SIGNAL when running task work · ef98eb04
    Nadav Amit authored
    When using SQPOLL, the submission queue polling thread calls
    task_work_run() to run queued work. However, when work is added with
    TWA_SIGNAL - as done by io_uring itself - the TIF_NOTIFY_SIGNAL remains
    set afterwards and is never cleared.
    
    Consequently, when the submission queue polling thread checks whether
    signal_pending(), it may always find a pending signal, if
    task_work_add() was ever called before.
    
    The impact of this bug might be different on different kernel versions.
    It appears that on 5.14 it would only cause unnecessary calculation and
    prevent the polling thread from sleeping. On 5.13, where the bug was
    found, it stops the polling thread from finding newly submitted work.
    
    Instead of task_work_run(), use tracehook_notify_signal() that clears
    TIF_NOTIFY_SIGNAL. Test for TIF_NOTIFY_SIGNAL in addition to
    current->task_works to avoid a race in which task_works is cleared but
    the TIF_NOTIFY_SIGNAL is set.
    
    Fixes: 685fe7fe ("io-wq: eliminate the need for a manager thread")
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Pavel Begunkov <asml.silence@gmail.com>
    Signed-off-by: default avatarNadav Amit <namit@vmware.com>
    Link: https://lore.kernel.org/r/20210808001342.964634-2-namit@vmware.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
    ef98eb04
io_uring.c 253 KB