From: Bradley Morgan <brads@mainlining.org>
To: daniel.lezcano@oss.qualcomm.com
Cc: akpm@linux-foundation.org, heiko@sntech.de,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org,
peterz@infradead.org, rafael@kernel.org, tglx@kernel.org
Subject: Re: [PATCH 1/2] smpboot: Allow restricting per-CPU threads to a CPU mask
Date: Tue, 03 Nov 2026 11:48:52 +0000 [thread overview]
Message-ID: <79AC1B3F-F158-4808-AD7E-70AE659E8DB5@mainlining.org> (raw)
In-Reply-To: <af37c4e7811a86adafb2064e7cf4aa4f5090ab4b.1793660202.git.daniel.lezcano@oss.qualcomm.com>
On 2 November 2026 23:09:40 GMT, Daniel Lezcano
<daniel.lezcano@oss.qualcomm.com> wrote:
>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.
>
This is simple as it gets, thanks.
Reviewed-by: Bradley Morgan <brads@mainlining.org>
>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)
> {
>
--- Thanks!
next prev parent reply other threads:[~2026-11-03 11:49 UTC|newest]
Thread overview: 3+ 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
2026-11-03 11:48 ` Bradley Morgan [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=79AC1B3F-F158-4808-AD7E-70AE659E8DB5@mainlining.org \
--to=brads@mainlining.org \
--cc=akpm@linux-foundation.org \
--cc=daniel.lezcano@oss.qualcomm.com \
--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®