diff options
author | Vincent Guittot <vincent.guittot@linaro.org> | 2015-11-20 15:29:19 +0100 |
---|---|---|
committer | Vincent Guittot <vincent.guittot@linaro.org> | 2015-11-20 15:43:43 +0100 |
commit | 2a1031275f37fbc57f59fcac1e4c5eb201cba8a4 (patch) | |
tree | e17d4927901885a907a3e191f4a7ed20147d15f1 | |
parent | e73e85f0593832aa583b252f9a16cf90ed6d30fa (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.c | 23 |
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; |