Re: [RFC PATCH RESEND 01/10] sched/fair: Do not set_rd_overloaded() if rd->online != env->cpus
From: Xin Zhao
Date: Fri Sep 11 2026 - 21:49:19 EST
On Fri, 11 Sep 2026 11:51:10 +0530 K Prateek Nayak <kprateek.nayak@xxxxxxx> wrote:
> What is the point of doing load balancing if the CPUs that are overloaded
> have all their tasks pinned? Those are just wasted cycles.
I don't think so. I sometimes make basic mistakes, so I'll express my complete
viewpoint, and you can check if there's anything wrong with what I'm saying below:
The simplified code in can_migrate_task() related LBF_ALL_PINNED is as follows:
The simplified code in can_migrate_task() related LBF_ALL_PINNED is as follows:
static
int can_migrate_task(struct task_struct *p, struct lb_env *env)
{
...
if (!cpumask_test_cpu(env->dst_cpu, p->cpus_ptr)) {
...
if (env->idle == CPU_NEWLY_IDLE ||
env->flags & (LBF_DST_PINNED | LBF_ACTIVE_LB))
return 0;
/* Prevent to re-select dst_cpu via env's CPUs: */
cpu = cpumask_first_and_and(env->dst_grpmask, env->cpus, p->cpus_ptr);
if (cpu < nr_cpu_ids) {
env->flags |= LBF_DST_PINNED;
env->new_dst_cpu = cpu;
}
return 0;
}
/* Record that we found at least one task that could run on dst_cpu */
env->flags &= ~LBF_ALL_PINNED;
...
}
Thus, LBF_ALL_PINNED does not mean that tasks are all pinned to their current CPU;
it merely indicates that tasks on the src CPU cannot be migrated to the dst CPU.
Example:
Assuming a system with two clusters, each containing two physical CPUs, the
structure is as follows:
DIE
USTER0 CLUSTER1
cpu0 cpu1 cpu2 cpu3
T0 p1,p2 p3 p4 p5
At time T0:
CPU0 has tasks p1 and p2, and both have a CPU mask of CPU0 and CPU2.
CPU1 has only task p3, with a CPU mask of CPU1.
CPU2 has only task `p4 with a CPU mask of CPU2.
CPU3 has only task p5, with a CPU mask of CPU3.
At time T1:
Task p5 on CPU3 goes to sleep, and then a newly load balance (newly lb) is
executed. It first looks for load balancing within CLUSTER1 and finds no tasks
to migrate.
It then goes up to the DIE level scheduling and finds the busiest CPU, which is
CPU0's queue. However, it discovers that none of the tasks can be migrated to
CPU3. Since this is a newly idle load balance, it won't perform the binding
check for whether other CPUs in env->dst_grpmask can serve as a CPU.
Consequently, it removes the busiest CPU (CPU0) from the CPU set, but CPU1
remains in the CPU set. Therefore, the check if
(!cpumask_subset(cpus, env.dst_grpmask)) {
passes leading to the redo phase.
Then it executes sched_balance_find_src_group(), followed by update_sd_lb_stats().
At this point, aside from CPU0, there is at most one task on the other CPUs,
causing the _overloaded flag in rd to be cleared.
At time T2:
Task p4 on CPU2 goes to sleep, and a newly idle load balance (newly lb) is
executed. However, since thesg_overloadedflag inrdhas been set,sched_balance_newidle()`
returns early.
But in reality, at this point, it is possible to migrate a task p1 to CPU2.
--
Xin Zhao