| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Chris Redpath <chris.redpath@arm.com> |
| Date: Tue, 5 Jun 2018 11:47:57 +0100 |
| Subject: ANDROID: sched/fair: Don't balance misfits if it would overload local |
| group |
| |
| When load balancing in a system with misfit tasks present, if we always |
| pull a misfit task to the local group this can lead to pulling a running |
| task from a smaller capacity CPUs to a bigger CPU which is busy. In this |
| situation, the pulled task is likely not to get a chance to run before |
| an idle balance on another small CPU pulls it back. This penalises the |
| pulled task as it is stopped for a short amount of time and then likely |
| relocated to a different CPU (since the original CPU just did a NEWLY_IDLE |
| balance and reset the periodic interval). |
| |
| If we only do this unconditionally for NEWLY_IDLE balance, we can be |
| sure that any tasks and load which are present on the local group are |
| related to short-running tasks which we are happy to displace for a |
| longer running task in a system with misfit tasks present. |
| |
| However, other balance types should only pull a task if we think |
| that the local group is underutilized - checking the number of tasks |
| gives us a conservative estimate here since if they were short tasks |
| we would have been doing NEWLY_IDLE balances instead. |
| |
| Change-Id: I710add1ab1139482620b6addc8370ad194791beb |
| Signed-off-by: Chris Redpath <chris.redpath@arm.com> |
| Signed-off-by: Quentin Perret <quentin.perret@arm.com> |
| --- |
| kernel/sched/fair.c | 14 ++++++++++++-- |
| 1 file changed, 12 insertions(+), 2 deletions(-) |
| |
| diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c |
| index 3b24b834d286..378fd22a372a 100644 |
| --- a/kernel/sched/fair.c |
| +++ b/kernel/sched/fair.c |
| @@ -8537,8 +8537,18 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s |
| (sds->avg_load - local->avg_load) * local->group_capacity |
| ) / SCHED_CAPACITY_SCALE; |
| |
| - /* Boost imbalance to allow misfit task to be balanced. */ |
| - if (busiest->group_type == group_misfit_task) { |
| + /* Boost imbalance to allow misfit task to be balanced. |
| + * Always do this if we are doing a NEWLY_IDLE balance |
| + * on the assumption that any tasks we have must not be |
| + * long-running (and hence we cannot rely upon load). |
| + * However if we are not idle, we should assume the tasks |
| + * we have are longer running and not override load-based |
| + * calculations above unless we are sure that the local |
| + * group is underutilized. |
| + */ |
| + if (busiest->group_type == group_misfit_task && |
| + (env->idle == CPU_NEWLY_IDLE || |
| + local->sum_nr_running < local->group_weight)) { |
| env->imbalance = max_t(long, env->imbalance, |
| busiest->group_misfit_task_load); |
| } |