aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Guittot <vincent.guittot@linaro.org>2015-11-20 15:29:19 +0100
committerVincent Guittot <vincent.guittot@linaro.org>2015-11-20 15:43:43 +0100
commit2a1031275f37fbc57f59fcac1e4c5eb201cba8a4 (patch)
treee17d4927901885a907a3e191f4a7ed20147d15f1
parente73e85f0593832aa583b252f9a16cf90ed6d30fa (diff)
sched/fair: update scale invariance of peltsched-pelt
The current implementation of load tracking invariance scales the load tracking value with current frequency and uarch performance (only for utilization) of the local CPU. One main result of the current formula is that the figures are capped by the current capacity of the local CPU. This limitation is the main reason of not including the uarch invariance in the calculation of load_avg. Instead of scaling the complete value of PELT algo, we should only scale the running time by current freq and uarch of the local CPU. It seems more correct to only scale the running time because the non running time (sleeping or waiting for a runqueue) of a task is the same whatever the current freq and the compute capacity of the local CPU. Then, one main advantage of this change is that the load of a task can reach max value whatever the current freq and the uarch of the local CPU. It will just take more time at a lower freq than the max freq or on a "little" CPU compared to a "big" one. The load and the utilization stay invariant across system but with a wider range of value. With this change, we don't have to test if a CPU is overloaded or not in order to use one metric or another as all metrics are always valid. Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
-rw-r--r--kernel/sched/fair.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 824aa9f501a3..d81e40363010 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2584,8 +2584,10 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
return 0;
sa->last_update_time = now;
- scale_freq = arch_scale_freq_capacity(NULL, cpu);
- scale_cpu = arch_scale_cpu_capacity(NULL, cpu);
+ if (running) {
+ delta = cap_scale(delta, arch_scale_freq_capacity(NULL, cpu));
+ delta = cap_scale(delta, arch_scale_cpu_capacity(NULL, cpu));
+ }
/* delta_w is the amount already accumulated against our next period */
delta_w = sa->period_contrib;
@@ -2601,16 +2603,15 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
* period and accrue it.
*/
delta_w = 1024 - delta_w;
- scaled_delta_w = cap_scale(delta_w, scale_freq);
if (weight) {
- sa->load_sum += weight * scaled_delta_w;
+ sa->load_sum += weight * delta_w;
if (cfs_rq) {
cfs_rq->runnable_load_sum +=
- weight * scaled_delta_w;
+ weight * delta_w;
}
}
if (running)
- sa->util_sum += scaled_delta_w * scale_cpu;
+ sa->util_sum += delta_w << SCHED_CAPACITY_SHIFT;
delta -= delta_w;
@@ -2627,25 +2628,23 @@ __update_load_avg(u64 now, int cpu, struct sched_avg *sa,
/* Efficiently calculate \sum (1..n_period) 1024*y^i */
contrib = __compute_runnable_contrib(periods);
- contrib = cap_scale(contrib, scale_freq);
if (weight) {
sa->load_sum += weight * contrib;
if (cfs_rq)
cfs_rq->runnable_load_sum += weight * contrib;
}
if (running)
- sa->util_sum += contrib * scale_cpu;
+ sa->util_sum += contrib << SCHED_CAPACITY_SHIFT;
}
/* Remainder of delta accrued against u_0` */
- scaled_delta = cap_scale(delta, scale_freq);
if (weight) {
- sa->load_sum += weight * scaled_delta;
+ sa->load_sum += weight * delta;
if (cfs_rq)
- cfs_rq->runnable_load_sum += weight * scaled_delta;
+ cfs_rq->runnable_load_sum += weight * delta;
}
if (running)
- sa->util_sum += scaled_delta * scale_cpu;
+ sa->util_sum += delta << SCHED_CAPACITY_SHIFT;
sa->period_contrib += delta;