Re: [PATCH 4/4] sched/fair: Prefer fully-idle SMT core for NOHZ idle load balancer

From: Shrikanth Hegde

Date: Fri Mar 27 2026 - 09:51:50 EST




On 3/26/26 8:32 PM, Andrea Righi wrote:
When choosing which idle housekeeping CPU runs the idle load balancer,
prefer one on a fully idle core if SMT is active, so balance can migrate
work onto a CPU that still offers full effective capacity. Fall back to
any idle candidate if none qualify.

Cc: Vincent Guittot <vincent.guittot@xxxxxxxxxx>
Cc: Dietmar Eggemann <dietmar.eggemann@xxxxxxx>
Cc: Christian Loehle <christian.loehle@xxxxxxx>
Cc: Koba Ko <kobak@xxxxxxxxxx>
Reported-by: Felix Abecassis <fabecassis@xxxxxxxxxx>
Signed-off-by: Andrea Righi <arighi@xxxxxxxxxx>
---
kernel/sched/fair.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 593a89f688679..a1ee21f7b32f6 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -12733,11 +12733,15 @@ static inline int on_null_domain(struct rq *rq)
* - When one of the busy CPUs notices that there may be an idle rebalancing
* needed, they will kick the idle load balancer, which then does idle
* load balancing for all the idle CPUs.
+ *
+ * - When SMT is active, prefer a CPU on a fully idle core as the ILB
+ * target, so that when it runs balance it becomes the destination CPU
+ * and can accept migrated tasks with full effective capacity.
*/
static inline int find_new_ilb(void)
{
const struct cpumask *hk_mask;
- int ilb_cpu;
+ int ilb_cpu, fallback = -1;
hk_mask = housekeeping_cpumask(HK_TYPE_KERNEL_NOISE);
@@ -12746,11 +12750,22 @@ static inline int find_new_ilb(void)
if (ilb_cpu == smp_processor_id())
continue;
+#ifdef CONFIG_SCHED_SMT
+ if (!idle_cpu(ilb_cpu))
+ continue;
+
+ if (fallback < 0)
+ fallback = ilb_cpu;
+
+ if (!sched_smt_active() || is_core_idle(ilb_cpu))

is_core_idle does loop for all sublings and nohz.idle_cpus_mask
will have all siblings likely.

So that might turn out be a bit expensive on large SMT system such as SMT=4
Also, this is with interrupt disabled.

Will try to run this on powerpc system and see if simple benchmarks show anything.

+ return ilb_cpu;
+#else
if (idle_cpu(ilb_cpu))
return ilb_cpu;
+#endif
}
- return -1;
+ return fallback;
}
/*