lkml.org 
[lkml]   [2018]   [Jul]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [RFC PATCH v4 09/12] sched/fair: Introduce an energy estimation helper function
On Fri, Jul 06, 2018 at 06:04:44PM +0100, Quentin Perret wrote:
> 'max_util' is basically the util we use to request an OPP. 'sum_util' is
> how long the CPUs will be running.

A indeed. But yes bit of a mess, but it wants doing I think.
Perhaps a little something like the below... The alternative is two
separate but closely related functions, not sure which is better.


enum schedutil_type {
frequency_util,
energy_util,
};

unsigned long
schedutil_freq_util(int cpu, unsigned long util_cfs, enum schedutil_type type)
{
struct rq *rq = cpu_rq(cpu);
unsigned long util, irq, max;

max = arch_scale_cpu_capacity(NULL, cpu);

if (type == frequency_util && rt_rq_is_runnable(&rq->rt))
return max;

/*
* Early check to see if IRQ/steal time saturates the CPU, can be
* because of inaccuracies in how we track these -- see
* update_irq_load_avg().
*/
irq = cpu_util_irq(rq);
if (unlikely(irq >= max))
return max;

/*
* Because the time spend on RT/DL tasks is visible as 'lost' time to
* CFS tasks and we use the same metric to track the effective
* utilization (PELT windows are synchronized) we can directly add them
* to obtain the CPU's actual utilization.
*/
util = util_cfs;
util += cpu_util_rt(rq);

if (type == frequency_util) {
/*
* For frequency selection we do not make cpu_util_dl()
* a permanent part of this sum because we want to use
* cpu_bw_dl() later on, but we need to check if the
* CFS+RT+DL sum is saturated (ie. no idle time) such
* that we select f_max when there is no idle time.
*
* NOTE: numerical errors or stop class might cause us
* to not quite hit saturation when we should --
* something for later.
*/
if ((util + cpu_util_dl(rq)) >= max)
return max;
} else {
/*
* OTOH, for energy computation we need the estimated
* running time, so include util_dl and ignore dl_bw.
*/
util += cpu_util_dl(rq);
if (util >= max)
return max;
}

/*
* There is still idle time; further improve the number by using the
* irq metric. Because IRQ/steal time is hidden from the task clock we
* need to scale the task numbers:
*
* 1 - irq
* U' = irq + ------- * U
* max
*/
util *= (max - irq);
util /= max;
util += irq;

if (type == frequency_util) {
/*
* Bandwidth required by DEADLINE must always be granted
* while, for FAIR and RT, we use blocked utilization of
* IDLE CPUs as a mechanism to gracefully reduce the
* frequency when no tasks show up for longer periods of
* time.
*
* Ideally we would like to set bw_dl as min/guaranteed
* freq and util + bw_dl as requested freq. However,
* cpufreq is not yet ready for such an interface. So,
* we only do the latter for now.
*/
util += cpu_bw_dl(rq);
}

return min(max, util);
}

\
 
 \ /
  Last update: 2018-07-09 14:03    [W:0.074 / U:0.856 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site