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>
This commit is contained in:

committed by
Quentin Perret

parent
f351885fc7
commit
a7455f8123
@@ -8509,8 +8509,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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user