Re: [PATCH v13 07/13] sched/fair: Load balance only among preferred CPUs

From: Yury Norov

Date: Wed Sep 09 2026 - 15:31:24 EST


On Wed, Sep 09, 2026 at 07:26:11PM +0530, Shrikanth Hegde wrote:
> When a CPU is marked as non-preferred, any load pulled towards it is
> pointless since the task will be pushed out again in the next tick.
> So, consider only preferred CPUs for load balancing.
>
> This ensures load balancing does not fight against the push task mechanism
> which happens at the tick. Also, this stops active balancing from happening
> on a non-preferred CPU pulling the load.
>
> This also means there is no load balancing if a task is pinned only to
> non-preferred CPUs. They will continue to run where they were previously
> running before the CPUs were marked as non-preferred.
>
> Bail out early for NEWIDLE balancing, as load balancing is done only on
> preferred CPUs. Note that idle balancing is allowed to go through, since
> that naturally updates nohz.next_balance when all the idle CPUs are
> non-preferred.
>
> Also, optimization in find_new_ilb() is skipped. The steal governor driver,
> which is introduced in later patches, updates the preferred CPUs state in
> descending order. find_new_ilb() checks for idle CPUs in ascending order.
> Hence, in most common scenarios, the idle CPU found by find_new_ilb() will
> already be a preferred CPU. When all idle CPUs are non-preferred, the first
> idle CPU has to be chosen anyway. All of this is naturally handled in
> find_new_ilb() currently. Adding additional complexity to it for rare
> edge cases is not necessary.
>
> Signed-off-by: Shrikanth Hegde <sshegde@xxxxxxxxxxxxx>

Reviewed-by: Yury Norov <ynorov@xxxxxxxxxx>

> ---
> kernel/sched/fair.c | 8 +++-----
> 1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index b8bd308c2d5b..4ef1167b8c73 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -13473,7 +13473,7 @@ static int sched_balance_rq(int this_cpu, struct rq *this_rq,
> };
> bool need_unlock = false;
>
> - cpumask_and(cpus, sched_domain_span(sd), cpu_active_mask);
> + cpumask_and(cpus, sched_domain_span(sd), cpu_preferred_mask);
>
> schedstat_inc(sd->lb_count[idle]);
>
> @@ -14588,10 +14588,8 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf)
> */
> this_rq->idle_stamp = rq_clock(this_rq);
>
> - /*
> - * Do not pull tasks towards !active CPUs...
> - */
> - if (!cpu_active(this_cpu))
> + /* Do not pull tasks towards !preferred CPUs */
> + if (!cpu_preferred(this_cpu))
> return 0;
>
> /*
> --
> 2.52.0