diff options
author | Vincent Guittot <vincent.guittot@linaro.org> | 2014-10-24 10:51:48 +0200 |
---|---|---|
committer | Vincent Guittot <vincent.guittot@linaro.org> | 2014-11-20 09:38:12 +0100 |
commit | 59326ac0e8f9f536d7fdfcb0c915299f7c514778 (patch) | |
tree | 89d429cd5f16121308c3888b5155c1138ae0b424 /kernel/sched/fair.c | |
parent | 31ec080432d339dddf5341ca82449181e4789ded (diff) |
sched: make scale_rt invariant with frequency
The average running time of RT tasks is used to estimate the remaining compute
capacity for CFS tasks. This remaining capacity is the original capacity scaled
down by a factor (aka scale_rt_capacity). This estimation of available capacity
must also be invariant with frequency scaling.
A frequency scaling factor is applied on the running time of the RT tasks for
computing scale_rt_capacity.
In sched_rt_avg_update, we scale the RT execution time like below:
rq->rt_avg += rt_delta * arch_scale_freq_capacity() >> SCHED_CAPACITY_SHIFT
Then, scale_rt_capacity can be summarized by:
scale_rt_capacity = SCHED_CAPACITY_SCALE -
((rq->rt_avg << SCHED_CAPACITY_SHIFT) / period)
We can optimize by removing right and left shift in the computation of rq->rt_avg
and scale_rt_capacity
The call to arch_scale_frequency_capacity in the rt scheduling path might be
a concern for RT folks because I'm not sure whether we can rely on
arch_scale_freq_capacity to be short and efficient ?
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
Diffstat (limited to 'kernel/sched/fair.c')
-rw-r--r-- | kernel/sched/fair.c | 17 |
1 files changed, 5 insertions, 12 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 72cf07497ad4..758ed78d6a48 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5988,7 +5988,7 @@ unsigned long __weak arch_scale_cpu_capacity(struct sched_domain *sd, int cpu) static unsigned long scale_rt_capacity(int cpu) { struct rq *rq = cpu_rq(cpu); - u64 total, available, age_stamp, avg; + u64 total, used, age_stamp, avg; s64 delta; /* @@ -6004,19 +6004,12 @@ static unsigned long scale_rt_capacity(int cpu) total = sched_avg_period() + delta; - if (unlikely(total < avg)) { - /* Ensures that capacity won't end up being negative */ - available = 0; - } else { - available = total - avg; - } + used = div_u64(avg, total); - if (unlikely((s64)total < SCHED_CAPACITY_SCALE)) - total = SCHED_CAPACITY_SCALE; + if (likely(used < SCHED_CAPACITY_SCALE)) + return SCHED_CAPACITY_SCALE - used; - total >>= SCHED_CAPACITY_SHIFT; - - return div_u64(available, total); + return 1; } static void update_cpu_capacity(struct sched_domain *sd, int cpu) |