[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <0028d3ea-4d05-405f-b457-75c83d381d89@kernel.dk>
Date: Tue, 11 Aug 2020 08:25:20 -0600
From: Jens Axboe <axboe@...nel.dk>
To: "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Cc: Oleg Nesterov <oleg@...hat.com>,
Peter Zijlstra <peterz@...radead.org>
Subject: [PATCH] task_work: only grab task signal lock when needed
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().
Signed-off-by: Jens Axboe <axboe@...nel.dk>
---
Tested this with an intensive task_work based io_uring workload, and
the benefits are quite large.
diff --git a/kernel/task_work.c b/kernel/task_work.c
index 5c0848ca1287..cbf8cab6e864 100644
--- a/kernel/task_work.c
+++ b/kernel/task_work.c
@@ -42,7 +42,8 @@ task_work_add(struct task_struct *task, struct callback_head *work, int notify)
set_notify_resume(task);
break;
case TWA_SIGNAL:
- if (lock_task_sighand(task, &flags)) {
+ if (!(READ_ONCE(task->jobctl) & JOBCTL_TASK_WORK) &&
+ lock_task_sighand(task, &flags)) {
task->jobctl |= JOBCTL_TASK_WORK;
signal_wake_up(task, 0);
unlock_task_sighand(task, &flags);
--
Jens Axboe
Powered by blists - more mailing lists