diff options
author | Vincent Guittot <vincent.guittot@linaro.org> | 2020-07-10 17:24:26 +0200 |
---|---|---|
committer | Vincent Guittot <vincent.guittot@linaro.org> | 2020-07-17 15:19:26 +0200 |
commit | 151f76910e6315ebc516f3a05a17aac431a07fef (patch) | |
tree | 3a4bb3ce245d6cd06c3e2d388342faac1ec36e03 | |
parent | 665a45788e4195f198e149c51defd186c8ef6548 (diff) |
sched/fair: handle case of task_h_load() returning 0sched/backport-h_load-v4.4.230
[ Upstream commit a61fa2799ef9bf6c4f54cf7295036577cececc72 ]
task_h_load() can return 0 in some situations like running stress-ng
mmapfork, which forks thousands of threads, in a sched group on a 224 cores
system. The load balance doesn't handle this correctly because
env->imbalance never decreases and it will stop pulling tasks only after
reaching loop_max, which can be equal to the number of running tasks of
the cfs. Make sure that imbalance will be decreased by at least 1.
We can't simply ensure that task_h_load() returns at least one because it
would imply to handle underflow in other places.
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Valentin Schneider <valentin.schneider@arm.com>
Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: <stable@vger.kernel.org> # v5.4
Link: https://lkml.kernel.org/r/20200710152426.16981-1-vincent.guittot@linaro.org
-rw-r--r-- | kernel/sched/fair.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 971e31e47bfd..15952d0e340b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5939,7 +5939,15 @@ static int detach_tasks(struct lb_env *env) if (!can_migrate_task(p, env)) goto next; - load = task_h_load(p); + /* + * Depending of the number of CPUs and tasks and the + * cgroup hierarchy, task_h_load() can return a null + * value. Make sure that env->imbalance decreases + * otherwise detach_tasks() will stop only after + * detaching up to loop_max tasks. + */ + load = max_t(unsigned long, task_h_load(p), 1); + if (sched_feat(LB_MIN) && load < 16 && !env->sd->nr_balance_failed) goto next; |