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 <[email protected]>

Reviewed-by: Yury Norov <[email protected]>

> ---
>  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

Reply via email to