From: Shrikanth Hegde <sshegde@linux.ibm.com>
To: Yury Norov <ynorov@nvidia.com>
Cc: linux-kernel@vger.kernel.org, mingo@kernel.org,
peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, yury.norov@gmail.com,
kprateek.nayak@amd.com, iii@linux.ibm.com, corbet@lwn.net,
tglx@kernel.org, gregkh@linuxfoundation.org, pbonzini@redhat.com,
seanjc@google.com, vschneid@redhat.com, huschle@linux.ibm.com,
rostedt@goodmis.org, dietmar.eggemann@arm.com,
maddy@linux.ibm.com, srikar@linux.ibm.com, hdanton@sina.com,
chleroy@kernel.org, vineeth@bitbyteword.org, frederic@kernel.org,
arighi@nvidia.com, pauld@redhat.com, christian.loehle@arm.com,
tj@kernel.org, tommaso.cucinotta@gmail.com, maz@kernel.org,
rafael@kernel.org, rdunlap@infradead.org, kernellwp@gmail.com,
linux-doc@vger.kernel.org
Subject: Re: [PATCH v6 18/23] virt/steal_monitor: Provide default method to inc/dec preferred CPUs
Date: Mon, 6 Jul 2026 14:50:21 +0530 [thread overview]
Message-ID: <929e1275-a568-45aa-909f-8ffcf859d7cb@linux.ibm.com> (raw)
In-Reply-To: <akglZQrZ0ghbwLth@yury>
Hi Yury,
On 7/4/26 2:41 AM, Yury Norov wrote:
> On Wed, Jul 01, 2026 at 07:46:49PM +0530, Shrikanth Hegde wrote:
>> These methods will be used by the steal_monitor core in subsequent
>> patches. Default implementation are likely good enough for most archs.
>>
>> decrease_preferred_cpus() - Called when there is high steal time. It needs
>> to decide which CPUs to mark as non-preferred and set that state.
>> increase_preferred_cpus() - Called when there is low steal time. It needs
>> to decide which CPUs to mark as preferred and set that state.
>>
>> Default Implementations:
>> decrease_preferred_cpus()
>> - Get first housekeeping CPU and its core mask. Mark it as
>> protected core. This helps to keep at least one core as preferred.
>
> Is there any measurable difference to manage preferred CPUs per-core
> vs per-cpu? If not, I'd choose to per-cpu version as it's simpler.
>
Yes, per-core is much better.
Since powerpc is SMT8 and phyp does core scheduling, taking on/off a full core makes a difference.
Even for other arch having it per core (SMT2 is being most common) it better IMO.
It allows to achieve the same level of packing without aggressive interval_ms.
>> This is to be safe under non-normal cases.
>> - Find the last CPU outside of this protected core mask. (target CPU)
>> This works for cases where one may specify nohz_full= for last set of
>> CPUs as well.
>
> And doesn't work for cases where one specifies nohz_full for the first
> set of CPUs. If you want to do it properly, you need two passes:
> 1. Search for preferred nohz_full candidates, and
> 2. If no such CPU found, search for any preferred CPU.
>
It works, in that case protected core is one outside of nohz_full list.
I have tried on the system.
I have 480 CPUs. (60 cores SMT8) I see this happening.
If nohz_full=<0-239> protected core will be 240-247
(CPUs 240-479 are part of HK_TYPE_KERNEL_NOISE)
if nohz_full=<240-479> protected core is 0-7
(CPUs 0-239 are part of HK_TYPE_KERNEL_NOISE)
If i pass nohz_full=0-479, then i see below in dmesg.
Housekeeping: must include one present CPU, using boot CPU:0
cat nohz_full
1-479
In that case too, protected core is 0-7
>> - If no such CPU exits, then only housekeeping core remains. Bail out.
>> - Based on that target CPU, get its sibling and mark them as
>> non-preferred. If they are nohz_full, enable the tick.
>> push mechanism relies on sched_tick.
>>
>> increase_preferred_cpus()
>> - Get the first active non-preferred CPUs. This likely is the last
>> set of CPUs being marked as non-preferred.
>> - If there is no such CPU, i.e preferred is same as active. Nothing
>> todo further.
>> - If not, get the siblings of that core and mark them as preferred.
>> Note that clearing the tick isn't needed as that would be handled via
>> sched_can_stop_tick.
>>
>> Using core instead of individual CPUs give better numbers as SMT is
>> quite common and some hypervisor such as powerVM does core scheduling.
>>
>> Note: This doesn't do any NUMA splicing to keep the code simpler and
>> minimal overhead. current code expects CPUs spread unformly
>> across NUMA nodes.
>>
>> Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
>> ---
>> v5->v6:
>> - Make it work for all cases when nohz_full= may be specified.
>>
>> drivers/virt/steal_monitor/defaults.c | 74 +++++++++++++++++++++++++++
>> drivers/virt/steal_monitor/sm_core.h | 2 +
>> 2 files changed, 76 insertions(+)
>>
>> diff --git a/drivers/virt/steal_monitor/defaults.c b/drivers/virt/steal_monitor/defaults.c
>> index 6681f9938f6a..4e2e5b233948 100644
>> --- a/drivers/virt/steal_monitor/defaults.c
>> +++ b/drivers/virt/steal_monitor/defaults.c
>> @@ -26,3 +26,77 @@ u64 __weak get_system_steal_time(void)
>>
>> return total_steal;
>> }
>> +
>> +/*
>> + * Default implementation of decrementing the preferred CPUs based on steal
>> + * time. This is simple logic and decrease the preferred CPUs by 1 core.
>> + * It takes out the last core in the active & preferred.
>> + *
>> + * Ensure at least one housekeeping core is always kept as preferred
>> + *
>> + * Could be overwritten by arch specific handling. Arch must ensure
>> + * preferred is always subset of active.
>> + */
>> +
>> +#define get_core_mask(cpu) topology_sibling_cpumask(cpu)
>
> useless redefinition.
that was keep for loop under 80 chars. I can drop it.
>
>> +
>> +void __weak decrease_preferred_cpus(struct steal_monitor *ctx)
>> +{
>> + int tmp_cpu, first_hk_cpu;
>> + const struct cpumask *first_hk_core;
>> + int target_cpu = nr_cpu_ids;
>> +
>> + guard(cpus_read_lock)();
>> +
>> + first_hk_cpu = cpumask_first_and(housekeeping_cpumask(HK_TYPE_KERNEL_NOISE),
>> + cpu_active_mask);
>
> Why active mask? If you want to preserve a cpu in preferred mask,
> search the cpu_preferred_mask.
>
> Can you explain why HK_TYPE_KERNEL_NOISE? Honestly, I don't
> understand the idea behind this logic.
HK_TYPE_KERNEL_NOISE logic is, kernel ensures atleast one CPU is always left and it
can't be hotplugged. So use that core for the protected core, as leaving atleast one
core as preferred is better.
Whole logic (this patch and Patch 23 is to ensure that) is leave that core as preferred.
For example, I have 480 CPUs. (60 cores SMT8)
If nohz_full=<0-239> protected core will be 240-247
(CPUs 240-479 are part of HK_TYPE_KERNEL_NOISE)
if nohz_full=<240-479> protected core is 0-7
(CPUs 0-239 are part of HK_TYPE_KERNEL_NOISE)
I see that happening with the patch series.
>
>> +
>> + if (first_hk_cpu >= nr_cpu_ids)
>> + return;
>> +
>> + first_hk_core = get_core_mask(first_hk_cpu);
>> +
>> + /* Always leave first housekeeping core as preferred. */
>> + for_each_cpu_andnot(tmp_cpu, cpu_preferred_mask, first_hk_core)
>> + target_cpu = tmp_cpu;
>> +
>> + /* Only the first housekeeping core remains */
>> + if (target_cpu >= nr_cpu_ids)
>> + return;
>> +
>> + /*
>> + * set tick bit for nohz_full CPU to push the task out. Once the tasks
>> + * are pushed out, bit will be cleared if there are no tasks.
>> + */
>> +
>> + for_each_cpu_and(tmp_cpu, get_core_mask(target_cpu), cpu_active_mask) {
>
> Why active mask here? It should be preferred, I guess? If you traverse
> the active mask, you're at least doing an extra work by disabling the
> already disabled CPUs, and probably have some side effects by calling
> tick_nohz_dep_set_cpu() twice.
Ok. I think preferred is better here.
But active also shouldn't cause any issue i think, since target_cpu is expected
to be a preferred CPU. So there is no double disable.
If there is was hotplug done, then it won;t be there in active too.
It takes cpus_read_lock to be safe against hotplug happening in parallel.
>
>> + set_cpu_preferred(tmp_cpu, false);
>> + if (tick_nohz_full_cpu(tmp_cpu))
>> + tick_nohz_dep_set_cpu(tmp_cpu, TICK_DEP_BIT_SCHED);
>> + }
>> +}
>> +
>> +/*
>> + * Default implementation of incrementing preferred CPUs based on steal
>> + * time. This is simple logic and increases the preferred CPUs by 1 core.
>> + * It adds the first core in active & !preferred
>> + *
>> + * Nothing to do if active == preferred
>> + *
>> + * Could be overwritten by arch specific handling. Arch must ensure
>> + * preferred is subset of active.
>> + */
>> +void __weak increase_preferred_cpus(struct steal_monitor *ctx)
>> +{
>> + int first_cpu, tmp_cpu;
>> +
>> + guard(cpus_read_lock)();
>> +
>> + first_cpu = cpumask_first_andnot(cpu_active_mask, cpu_preferred_mask);
>> + /* All CPUs are preferred. Nothing to increase further */
>> + if (first_cpu >= nr_cpu_ids)
>> + return;
>> +
>> + for_each_cpu_and(tmp_cpu, get_core_mask(first_cpu), cpu_active_mask)
>
> Here I agree, it should be cpu_active_mask.
Yes.
>
>> + set_cpu_preferred(tmp_cpu, true);
>> +}
>> diff --git a/drivers/virt/steal_monitor/sm_core.h b/drivers/virt/steal_monitor/sm_core.h
>> index 634c9f5a2610..030f6236c38e 100644
>> --- a/drivers/virt/steal_monitor/sm_core.h
>> +++ b/drivers/virt/steal_monitor/sm_core.h
>> @@ -26,5 +26,7 @@ struct steal_monitor {
>> extern struct steal_monitor sm_core_ctx;
>>
>> u64 get_system_steal_time(void);
>> +void increase_preferred_cpus(struct steal_monitor *ctx);
>> +void decrease_preferred_cpus(struct steal_monitor *ctx);
>>
>> #endif /* __VIRT_STEAL_CORE_H */
>> --
>> 2.47.3
next prev parent reply other threads:[~2026-07-06 9:20 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 14:16 [PATCH v6 00/23] sched: Introduce cpu_preferred_mask and steal-driven vCPU backoff Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 01/23] sched/docs: Document cpu_preferred_mask and Preferred CPU concept Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 02/23] kconfig: Provide PREFERRED_CPU option Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 03/23] cpumask: Introduce cpu_preferred_mask Shrikanth Hegde
2026-07-01 15:35 ` Yury Norov
2026-07-01 16:40 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 04/23] sysfs: Add preferred CPU file Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 05/23] sched/core: Try to use a preferred CPU in is_cpu_allowed Shrikanth Hegde
2026-07-01 16:09 ` Yury Norov
2026-07-01 16:49 ` Shrikanth Hegde
2026-07-02 6:30 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 06/23] sched/fair: Load balance only among preferred CPUs Shrikanth Hegde
2026-07-01 16:19 ` Yury Norov
2026-07-01 16:41 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 07/23] sched/fair: Pull the load on preferred CPU Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 08/23] sched/core: Keep tick on non-preferred CPUs until tasks are out Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 09/23] sched/core: Push current task from non preferred CPU Shrikanth Hegde
2026-07-01 16:50 ` Yury Norov
2026-07-01 17:03 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 10/23] sched/debug: Add migration stats due to non preferred CPUs Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 11/23] virt/steal_monitor: Add documentation Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 12/23] virt: Introduce steal monitor driver Shrikanth Hegde
2026-07-03 18:20 ` Yury Norov
2026-07-03 18:27 ` Yury Norov
2026-07-06 8:24 ` Shrikanth Hegde
2026-07-06 18:49 ` Yury Norov
2026-07-07 6:47 ` Shrikanth Hegde
2026-07-06 8:09 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 13/23] virt/steal_monitor: Restore to active on module disable Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 14/23] virt/steal_monitor: Define steal_monitor structure Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 15/23] virt/steal_monitor: Add control knobs for handling steal values Shrikanth Hegde
2026-07-02 7:16 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 16/23] virt/steal_monitor: Compute work at regular intervals Shrikanth Hegde
2026-07-03 18:14 ` Yury Norov
2026-07-06 8:38 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 17/23] virt/steal_monitor: Provide default method to get systemwide steal time Shrikanth Hegde
2026-07-03 19:16 ` Yury Norov
2026-07-06 8:47 ` Shrikanth Hegde
2026-07-06 19:04 ` Yury Norov
2026-07-07 6:50 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 18/23] virt/steal_monitor: Provide default method to inc/dec preferred CPUs Shrikanth Hegde
2026-07-03 21:11 ` Yury Norov
2026-07-06 9:20 ` Shrikanth Hegde [this message]
2026-07-01 14:16 ` [PATCH v6 19/23] virt/steal_monitor: Provide default method to get num of CPUs for steal ratio Shrikanth Hegde
2026-07-06 19:26 ` Yury Norov
2026-07-07 6:55 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 20/23] virt/steal_monitor: Act on steal values at regular intervals Shrikanth Hegde
2026-07-02 7:18 ` Shrikanth Hegde
2026-07-06 20:33 ` Yury Norov
2026-07-07 7:16 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 21/23] virt/steal_monitor: Add direction control Shrikanth Hegde
2026-07-06 20:36 ` Yury Norov
2026-07-07 7:16 ` Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 22/23] virt/steal_monitor: Add design check of preferred subset of active Shrikanth Hegde
2026-07-01 14:16 ` [PATCH v6 23/23] virt/steal_monitor: Optimise decrease_preferred_cpus when all CPUs are housekeeping Shrikanth Hegde
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=929e1275-a568-45aa-909f-8ffcf859d7cb@linux.ibm.com \
--to=sshegde@linux.ibm.com \
--cc=arighi@nvidia.com \
--cc=chleroy@kernel.org \
--cc=christian.loehle@arm.com \
--cc=corbet@lwn.net \
--cc=dietmar.eggemann@arm.com \
--cc=frederic@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=hdanton@sina.com \
--cc=huschle@linux.ibm.com \
--cc=iii@linux.ibm.com \
--cc=juri.lelli@redhat.com \
--cc=kernellwp@gmail.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maddy@linux.ibm.com \
--cc=maz@kernel.org \
--cc=mingo@kernel.org \
--cc=pauld@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=rafael@kernel.org \
--cc=rdunlap@infradead.org \
--cc=rostedt@goodmis.org \
--cc=seanjc@google.com \
--cc=srikar@linux.ibm.com \
--cc=tglx@kernel.org \
--cc=tj@kernel.org \
--cc=tommaso.cucinotta@gmail.com \
--cc=vincent.guittot@linaro.org \
--cc=vineeth@bitbyteword.org \
--cc=vschneid@redhat.com \
--cc=ynorov@nvidia.com \
--cc=yury.norov@gmail.com \
/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