Skip to content

Commit

Permalink
sched/core: Use PELT for scale_rt_capacity()
Browse files Browse the repository at this point in the history
The utilization of the CPU by RT, DL and IRQs are now tracked with
PELT so we can use these metrics instead of rt_avg to evaluate the remaining
capacity available for CFS class.

scale_rt_capacity() behavior has been changed and now returns the remaining
capacity available for CFS instead of a scaling factor because RT, DL and
IRQ provide now absolute utilization value.

The same formula as schedutil is used:

  IRQ util_avg + (1 - IRQ util_avg / max capacity ) * /Sum rq util_avg

but the implementation is different because it doesn't return the same value
and doesn't benefit of the same optimization.

Signed-off-by: Vincent Guittot <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: [email protected]
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
vingu-linaro authored and Ingo Molnar committed Jul 15, 2018
1 parent dfa444d commit 523e979
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 27 deletions.
2 changes: 0 additions & 2 deletions kernel/sched/deadline.c
Original file line number Diff line number Diff line change
Expand Up @@ -1180,8 +1180,6 @@ static void update_curr_dl(struct rq *rq)
curr->se.exec_start = now;
cgroup_account_cputime(curr, delta_exec);

sched_rt_avg_update(rq, delta_exec);

if (dl_entity_is_special(dl_se))
return;

Expand Down
44 changes: 22 additions & 22 deletions kernel/sched/fair.c
Original file line number Diff line number Diff line change
Expand Up @@ -7551,39 +7551,39 @@ static inline int get_sd_load_idx(struct sched_domain *sd,
static unsigned long scale_rt_capacity(int cpu)
{
struct rq *rq = cpu_rq(cpu);
u64 total, used, age_stamp, avg;
s64 delta;

/*
* Since we're reading these variables without serialization make sure
* we read them once before doing sanity checks on them.
*/
age_stamp = READ_ONCE(rq->age_stamp);
avg = READ_ONCE(rq->rt_avg);
delta = __rq_clock_broken(rq) - age_stamp;
unsigned long max = arch_scale_cpu_capacity(NULL, cpu);
unsigned long used, free;
#if defined(CONFIG_IRQ_TIME_ACCOUNTING) || defined(CONFIG_PARAVIRT_TIME_ACCOUNTING)
unsigned long irq;
#endif

if (unlikely(delta < 0))
delta = 0;
#if defined(CONFIG_IRQ_TIME_ACCOUNTING) || defined(CONFIG_PARAVIRT_TIME_ACCOUNTING)
irq = READ_ONCE(rq->avg_irq.util_avg);

total = sched_avg_period() + delta;
if (unlikely(irq >= max))
return 1;
#endif

used = div_u64(avg, total);
used = READ_ONCE(rq->avg_rt.util_avg);
used += READ_ONCE(rq->avg_dl.util_avg);

if (likely(used < SCHED_CAPACITY_SCALE))
return SCHED_CAPACITY_SCALE - used;
if (unlikely(used >= max))
return 1;

return 1;
free = max - used;
#if defined(CONFIG_IRQ_TIME_ACCOUNTING) || defined(CONFIG_PARAVIRT_TIME_ACCOUNTING)
free *= (max - irq);
free /= max;
#endif
return free;
}

static void update_cpu_capacity(struct sched_domain *sd, int cpu)
{
unsigned long capacity = arch_scale_cpu_capacity(sd, cpu);
unsigned long capacity = scale_rt_capacity(cpu);
struct sched_group *sdg = sd->groups;

cpu_rq(cpu)->cpu_capacity_orig = capacity;

capacity *= scale_rt_capacity(cpu);
capacity >>= SCHED_CAPACITY_SHIFT;
cpu_rq(cpu)->cpu_capacity_orig = arch_scale_cpu_capacity(sd, cpu);

if (!capacity)
capacity = 1;
Expand Down
2 changes: 1 addition & 1 deletion kernel/sched/pelt.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ ___update_load_avg(struct sched_avg *sa, unsigned long load, unsigned long runna
*/
sa->load_avg = div_u64(load * sa->load_sum, divider);
sa->runnable_load_avg = div_u64(runnable * sa->runnable_load_sum, divider);
sa->util_avg = sa->util_sum / divider;
WRITE_ONCE(sa->util_avg, sa->util_sum / divider);
}

/*
Expand Down
2 changes: 0 additions & 2 deletions kernel/sched/rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -973,8 +973,6 @@ static void update_curr_rt(struct rq *rq)
curr->se.exec_start = now;
cgroup_account_cputime(curr, delta_exec);

sched_rt_avg_update(rq, delta_exec);

if (!rt_bandwidth_enabled())
return;

Expand Down

0 comments on commit 523e979

Please sign in to comment.