[tip: sched/core] smpboot: Don't park the thread if work is pending

From: tip-bot2 for Sebastian Andrzej Siewior

Date: Fri Oct 02 2026 - 05:34:38 EST


The following commit has been merged into the sched/core branch of tip:

Commit-ID: 4a3b51aab6e25244d97936aa65e6d5425adf98e1
Gitweb: https://git.kernel.org/tip/4a3b51aab6e25244d97936aa65e6d5425adf98e1
Author: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
AuthorDate: Fri, 11 Sep 2026 16:38:14 +02:00
Committer: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
CommitterDate: Thu, 01 Oct 2026 14:00:36 +02:00

smpboot: Don't park the thread if work is pending

Once a smpboot thread gets work assigned it receives a wake up. If the
thread had no chance to run and receives a parking requesst during a
CPU-hotplug event then it is parked without running the callback first.
As a result the enqueued work remains stuck until the CPU gets back
online.

There is nothing wrong with invoking the thread function first and
parking in the following iteration. This would ensure that the callbacks
are processed before the shutdown.

Honor the park request once thread function does not need to run.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
Link: https://patch.msgid.link/20260911143815.997254-4-bigeasy@xxxxxxxxxxxxx
---
kernel/smpboot.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index 4503b60..3f60e8c 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -103,6 +103,7 @@ static int smpboot_thread_fn(void *data)
{
struct smpboot_thread_data *td = data;
struct smp_hotplug_thread *ht = td->ht;
+ bool should_run;

while (1) {
set_current_state(TASK_INTERRUPTIBLE);
@@ -117,7 +118,8 @@ static int smpboot_thread_fn(void *data)
return 0;
}

- if (kthread_should_park()) {
+ should_run = td->status == HP_THREAD_ACTIVE && ht->thread_should_run(td->cpu);
+ if (kthread_should_park() && !should_run) {
__set_current_state(TASK_RUNNING);
preempt_enable();
if (ht->park && td->status == HP_THREAD_ACTIVE) {
@@ -151,7 +153,7 @@ static int smpboot_thread_fn(void *data)
continue;
}

- if (!ht->thread_should_run(td->cpu)) {
+ if (!should_run) {
preempt_enable_no_resched();
schedule();
} else {