On 27/02/15 15:54, Vincent Guittot wrote:
Monitor the usage level of each group of each sched_domain level. The usage is the portion of cpu_capacity_orig that is currently used on a CPU or group of CPUs. We use the utilization_load_avg to evaluate the usage level of each group.
The utilization_load_avg only takes into account the running time of the CFS tasks on a CPU with a maximum value of SCHED_LOAD_SCALE when the CPU is fully utilized. Nevertheless, we must cap utilization_load_avg which can be temporaly
s/temporaly/temporally
greater than SCHED_LOAD_SCALE after the migration of a task on this CPU and until the metrics are stabilized.
The utilization_load_avg is in the range [0..SCHED_LOAD_SCALE] to reflect the running load on the CPU whereas the available capacity for the CFS task is in the range [0..cpu_capacity_orig]. In order to test if a CPU is fully utilized by CFS tasks, we have to scale the utilization in the cpu_capacity_orig range of the CPU to get the usage of the latter. The usage can then be compared with the available capacity (ie cpu_capacity) to deduct the usage level of a CPU.
The frequency scaling invariance of the usage is not taken into account in this patch, it will be solved in another patch which will deal with frequency scaling invariance on the running_load_avg.
The use of underscores in running_load_avg implies to me that this is a data member of struct sched_avg or something similar. But there is no running_load_avg in the current code. However, I can see that sched_avg::*running_avg_sum* (and therefore cfs_rq::*utilization_load_avg*) are frequency scale invariant.
Signed-off-by: Vincent Guittot vincent.guittot@linaro.org Acked-by: Morten Rasmussen morten.rasmussen@arm.com
kernel/sched/fair.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 10f84c3..faf61a2 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4781,6 +4781,33 @@ static int select_idle_sibling(struct task_struct *p, int target) done: return target; } +/*
- get_cpu_usage returns the amount of capacity of a CPU that is used by CFS
- tasks. The unit of the return value must capacity so we can compare the
s/must capacity/must be the one of capacity
- usage with the capacity of the CPU that is available for CFS task (ie
- cpu_capacity).
- cfs.utilization_load_avg is the sum of running time of runnable tasks on a
- CPU. It represents the amount of utilization of a CPU in the range
- [0..SCHED_LOAD_SCALE]. The usage of a CPU can't be higher than the full
- capacity of the CPU because it's about the running time on this CPU.
- Nevertheless, cfs.utilization_load_avg can be higher than SCHED_LOAD_SCALE
- because of unfortunate rounding in avg_period and running_load_avg or just
- after migrating tasks until the average stabilizes with the new running
- time. So we need to check that the usage stays into the range
- [0..cpu_capacity_orig] and cap if necessary.
- Without capping the usage, a group could be seen as overloaded (CPU0 usage
- at 121% + CPU1 usage at 80%) whereas CPU1 has 20% of available capacity/
s/capacity//capacity.
[...]
-- Dietmar