>From 232a5d9bf181b05d199ff3c3be7ab7c2b0b1898c Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 8 Jan 2021 09:17:45 -0700 Subject: [PATCH 2/4] task_work: always use signal work if notification is selected 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 --- 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