From: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
To: akpm@linux-foundation.org, rafael@kernel.org, tglx@kernel.org,
peterz@infradead.org
Cc: Heiko Stuebner <heiko@sntech.de>,
linux-arm-kernel@lists.infradead.org (moderated
list:ARM/Rockchip SoC support),
linux-rockchip@lists.infradead.org (open list:ARM/Rockchip SoC
support), linux-kernel@vger.kernel.org (open list:CPU HOTPLUG)
Subject: [PATCH 1/2] smpboot: Allow restricting per-CPU threads to a CPU mask
Date: Tue, 3 Nov 2026 00:09:40 +0100 [thread overview]
Message-ID: <af37c4e7811a86adafb2064e7cf4aa4f5090ab4b.1793660202.git.daniel.lezcano@oss.qualcomm.com> (raw)
In-Reply-To: <cover.1793660202.git.daniel.lezcano@oss.qualcomm.com>
smpboot_register_percpu_thread() creates a thread for every online CPU
and registers the descriptor for subsequent CPU hotplug operations.
There is currently no way to restrict these threads to a subset of
CPUs, even when the user only needs work performed on that subset.
For example, an idle injection device targets a specific CPU mask.
Creating threads outside that mask consumes resources unnecessarily.
Supporting multiple such devices also requires each descriptor to
manage only the threads associated with its own CPUs.
Add an optional CPU mask to struct smp_hotplug_thread and apply it
throughout the thread lifecycle. Registration creates threads only for
online CPUs in the mask. CPU bring-up creates threads for selected
CPUs that were offline at registration, while parking and unparking
are restricted to the same mask.
Apply the restriction to thread destruction as well, both during
unregistration and registration failure cleanup. This is necessary
when descriptors with disjoint masks share the same per-CPU task
storage: tearing down one descriptor must not stop or clear threads
owned by another descriptor.
The caller must keep the mask valid and unchanged until the descriptor
is unregistered. Callers sharing per-CPU task storage must ensure their
masks do not overlap and serialize ownership changes themselves.
A NULL mask preserves the existing behavior, so current users continue
to manage threads on all CPUs.
Signed-off-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
---
include/linux/smpboot.h | 4 ++++
kernel/smpboot.c | 17 +++++++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/include/linux/smpboot.h b/include/linux/smpboot.h
index 9d1bc65d226c..98c072eeaf24 100644
--- a/include/linux/smpboot.h
+++ b/include/linux/smpboot.h
@@ -5,6 +5,7 @@
#include <linux/types.h>
struct task_struct;
+struct cpumask;
/* Cookie handed to the thread_fn*/
struct smpboot_thread_data;
@@ -27,6 +28,8 @@ struct smpboot_thread_data;
* unparked (cpu online)
* @selfparking: Thread is not parked by the park function.
* @thread_comm: The base name of the thread
+ * @cpumask: Optional mask of CPUs on which to create threads. Must remain
+ * valid and unchanged until the descriptor is unregistered.
*/
struct smp_hotplug_thread {
struct task_struct * __percpu *store;
@@ -40,6 +43,7 @@ struct smp_hotplug_thread {
void (*unpark)(unsigned int cpu);
bool selfparking;
const char *thread_comm;
+ const struct cpumask *cpumask;
};
int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread);
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index 4503b60ce9bd..07857523a465 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -168,6 +168,9 @@ __smpboot_create_thread(struct smp_hotplug_thread *ht, unsigned int cpu)
struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu);
struct smpboot_thread_data *td;
+ if (ht->cpumask && !cpumask_test_cpu(cpu, ht->cpumask))
+ return 0;
+
if (tsk)
return 0;
@@ -225,6 +228,9 @@ static void smpboot_unpark_thread(struct smp_hotplug_thread *ht, unsigned int cp
{
struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu);
+ if (ht->cpumask && !cpumask_test_cpu(cpu, ht->cpumask))
+ return;
+
if (!ht->selfparking)
kthread_unpark(tsk);
}
@@ -244,6 +250,9 @@ static void smpboot_park_thread(struct smp_hotplug_thread *ht, unsigned int cpu)
{
struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu);
+ if (ht->cpumask && !cpumask_test_cpu(cpu, ht->cpumask))
+ return;
+
if (tsk && !ht->selfparking)
kthread_park(tsk);
}
@@ -267,6 +276,9 @@ static void smpboot_destroy_threads(struct smp_hotplug_thread *ht)
for_each_possible_cpu(cpu) {
struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu);
+ if (ht->cpumask && !cpumask_test_cpu(cpu, ht->cpumask))
+ continue;
+
if (tsk) {
kthread_stop_put(tsk);
*per_cpu_ptr(ht->store, cpu) = NULL;
@@ -279,7 +291,8 @@ static void smpboot_destroy_threads(struct smp_hotplug_thread *ht)
* to hotplug
* @plug_thread: Hotplug thread descriptor
*
- * Creates and starts the threads on all online cpus.
+ * Creates and starts the threads on online CPUs selected by the descriptor's
+ * cpumask, or all online CPUs if no mask is specified.
*/
int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread)
{
@@ -308,7 +321,7 @@ EXPORT_SYMBOL_GPL(smpboot_register_percpu_thread);
* smpboot_unregister_percpu_thread - Unregister a per_cpu thread related to hotplug
* @plug_thread: Hotplug thread descriptor
*
- * Stops all threads on all possible cpus.
+ * Stops all threads associated with the descriptor, including offline CPUs.
*/
void smpboot_unregister_percpu_thread(struct smp_hotplug_thread *plug_thread)
{
--
2.43.0
next parent reply other threads:[~2026-11-02 23:10 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1793660202.git.daniel.lezcano@oss.qualcomm.com>
2026-11-02 23:09 ` Daniel Lezcano [this message]
2026-11-02 23:09 ` [PATCH 2/2] powercap: idle_inject: Create per-CPU threads on registration Daniel Lezcano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=af37c4e7811a86adafb2064e7cf4aa4f5090ab4b.1793660202.git.daniel.lezcano@oss.qualcomm.com \
--to=daniel.lezcano@oss.qualcomm.com \
--cc=akpm@linux-foundation.org \
--cc=heiko@sntech.de \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=peterz@infradead.org \
--cc=rafael@kernel.org \
--cc=tglx@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®