task_work: only grab task signal lock when needed
authorJens Axboe <axboe@kernel.dk>
Thu, 13 Aug 2020 15:01:38 +0000 (09:01 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Aug 2020 06:24:19 +0000 (08:24 +0200)
commitfb910a7d69163ccfc962999bf404589c6072e827
tree34086618144f03a5f8b8a35a61aa2ef4d9ae909a
parentff3f5b7bdcfb2d0ed3e2d3ac7504b69d29a7871a
task_work: only grab task signal lock when needed

commit ebf0d100df0731901c16632f78d78d35f4123bc4 upstream.

If JOBCTL_TASK_WORK is already set on the targeted task, then we need
not go through {lock,unlock}_task_sighand() to set it again and queue
a signal wakeup. This is safe as we're checking it _after_ adding the
new task_work with cmpxchg().

The ordering is as follows:

task_work_add() get_signal()
--------------------------------------------------------------
STORE(task->task_works, new_work); STORE(task->jobctl);
mb(); mb();
LOAD(task->jobctl); LOAD(task->task_works);

This speeds up TWA_SIGNAL handling quite a bit, which is important now
that io_uring is relying on it for all task_work deliveries.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jann Horn <jannh@google.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
kernel/signal.c
kernel/task_work.c