[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20260205150846.1242134-3-pierre.gondois@arm.com>
Date: Thu, 5 Feb 2026 16:08:45 +0100
From: Pierre Gondois <pierre.gondois@....com>
To: linux-kernel@...r.kernel.org
Cc: Christian Loehle <christian.loehle@....com>,
Pierre Gondois <pierre.gondois@....com>,
Ingo Molnar <mingo@...hat.com>,
Peter Zijlstra <peterz@...radead.org>,
Juri Lelli <juri.lelli@...hat.com>,
Vincent Guittot <vincent.guittot@...aro.org>,
Dietmar Eggemann <dietmar.eggemann@....com>,
Steven Rostedt <rostedt@...dmis.org>,
Ben Segall <bsegall@...gle.com>,
Mel Gorman <mgorman@...e.de>,
Valentin Schneider <vschneid@...hat.com>,
Rik van Riel <riel@...riel.com>
Subject: [PATCH 2/2] sched/fair: Balance #Tasks/#CPUs if busiest group has no idle CPU
Balancing the number of idle CPUs between groups is done if:
- the busiest group is overloaded: sum_nr_running > #CPUs
- the local group has spare capacity: sum_nr_running <= #CPUs
To avoid pulling too many tasks and moving the imbalance to the
local group, the number of task pulled is half of:
(local->idle_cpus - busiest->idle_cpus)
Halving the imbalance currently lead to the following scenario.
On a Juno with 2 clusters: CLU0: 4 CPUs and CLU1: 2 CPUs, with
6 long running tasks:
- 1 task on the 2-CPUs cluster
- 5 Tasks run in the 4-CPUs cluster
Running the load balancer from the idle CPU (in CLU1):
- Local group: CLU1: idle_cpus=1; nr_running=1; type=group_has_spare
- Busiest group: CLU0 idle_cpus=0; nr_running=5 type=group_overloaded
Half of (local->idle_cpus - busiest->idle_cpus) is 0.
No task is migrated and the task placement persists.
Balancing number of idle CPUs is only relevant if the busiest group
has idle CPUs. Otherwise it is better to have an equal ratio
of #tasks / #CPUs.
sibling_imbalance() was also introduced to cope with groups with
asymmetric sizes. This is also the case here.
commit 7ff1693236f5 ("sched/fair: Implement prefer sibling
imbalance calculation between asymmetric groups")
Try to stay conservative and only balance the ratio
of #Tasks / #CPUs if the busiest group has no idle CPUs.
Note that a similar check present in update_pick_idlest()
is not updated.
Signed-off-by: Pierre Gondois <pierre.gondois@....com>
---
kernel/sched/fair.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index aa14a9982b9f1..9dac3536d9c19 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -11235,20 +11235,18 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s
return;
}
- if (busiest->group_weight == 1 || sds->prefer_sibling) {
+ env->migration_type = migrate_task;
+ if (busiest->group_weight == 1 || sds->prefer_sibling || !busiest->idle_cpus) {
/*
- * When prefer sibling, evenly spread running tasks on
- * groups.
+ * When prefer sibling, or when busiest has no idle CPU,
+ * evenly spread running tasks on groups.
*/
- env->migration_type = migrate_task;
env->imbalance = sibling_imbalance(env, sds, busiest, local);
} else {
-
/*
* If there is no overload, we just want to even the number of
* idle CPUs.
*/
- env->migration_type = migrate_task;
env->imbalance = local->idle_cpus;
lsub_positive(&env->imbalance, busiest->idle_cpus);
}
--
2.43.0
Powered by blists - more mailing lists