[PATCH 2/4] task_work: always use signal work if notification is selected

From: Jens Axboe
Date: Fri Jan 08 2021 - 11:17:45 EST


Since we run any task_work from get_signal(), there's no real distinction
between TWA_RESUME and TWA_SIGNAL. Turn the notification method for
task_work_add() into a boolean, in preparation for getting rid of the
difference between the two.

With TWA_SIGNAL always being used, we no longer need to check and run
task_work in get_signal() unconditionally. Get rid of it.

Signed-off-by: Jens Axboe <axboe@xxxxxxxxx>
---
include/linux/task_work.h | 2 +-
kernel/signal.c | 3 ---
kernel/task_work.c | 29 ++++++++---------------------
3 files changed, 9 insertions(+), 25 deletions(-)

diff --git a/include/linux/task_work.h b/include/linux/task_work.h
index 0d848a1e9e62..8df8d539fad8 100644
--- a/include/linux/task_work.h
+++ b/include/linux/task_work.h
@@ -20,7 +20,7 @@ enum task_work_notify_mode {
};

int task_work_add(struct task_struct *task, struct callback_head *twork,
- enum task_work_notify_mode mode);
+ bool notify);

struct callback_head *task_work_cancel(struct task_struct *, task_work_func_t);
void task_work_run(void);
diff --git a/kernel/signal.c b/kernel/signal.c
index 6b9c431da08f..5736c55aaa1a 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2550,9 +2550,6 @@ bool get_signal(struct ksignal *ksig)
struct signal_struct *signal = current->signal;
int signr;

- if (unlikely(current->task_works))
- task_work_run();
-
/*
* For non-generic architectures, check for TIF_NOTIFY_SIGNAL so
* that the arch handlers don't all have to do it. If we get here
diff --git a/kernel/task_work.c b/kernel/task_work.c
index 9cde961875c0..7a4850669033 100644
--- a/kernel/task_work.c
+++ b/kernel/task_work.c
@@ -9,15 +9,13 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */
* task_work_add - ask the @task to execute @work->func()
* @task: the task which should run the callback
* @work: the callback to run
- * @notify: how to notify the targeted task
+ * @notify: whether to notify the targeted task or not
*
- * Queue @work for task_work_run() below and notify the @task if @notify
- * is @TWA_RESUME or @TWA_SIGNAL. @TWA_SIGNAL works like signals, in that the
- * it will interrupt the targeted task and run the task_work. @TWA_RESUME
- * work is run only when the task exits the kernel and returns to user mode,
- * or before entering guest mode. Fails if the @task is exiting/exited and thus
- * it can't process this @work. Otherwise @work->func() will be called when the
- * @task goes through one of the aforementioned transitions, or exits.
+ * Queue @work for task_work_run() below and notify the @task if @notify is
+ * true. If notification is selected, the targeted task is interrupted so it
+ * can process the work. Fails if the @task is exiting/exited and thus it can't
+ * process this @work. Otherwise @work->func() will be called when the @task
+ * goes through one of the aforementioned transitions, or exits.
*
* If the targeted task is exiting, then an error is returned and the work item
* is not queued. It's up to the caller to arrange for an alternative mechanism
@@ -30,7 +28,7 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */
* 0 if succeeds or -ESRCH.
*/
int task_work_add(struct task_struct *task, struct callback_head *work,
- enum task_work_notify_mode notify)
+ bool notify)
{
struct callback_head *head;

@@ -41,19 +39,8 @@ int task_work_add(struct task_struct *task, struct callback_head *work,
work->next = head;
} while (cmpxchg(&task->task_works, head, work) != head);

- switch (notify) {
- case TWA_NONE:
- break;
- case TWA_RESUME:
- set_notify_resume(task);
- break;
- case TWA_SIGNAL:
+ if (notify)
set_notify_signal(task);
- break;
- default:
- WARN_ON_ONCE(1);
- break;
- }

return 0;
}
--
2.30.0


--------------DB179B50B84C45A6F2CE09AA
Content-Type: text/x-patch; charset=UTF-8;
name="0001-task_work-unconditionally-run-task_work-from-get_sig.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename*0="0001-task_work-unconditionally-run-task_work-from-get_sig.pa";
filename*1="tch"