Quoting Ashwin Chaugule (2015-04-17 11:37:44)
On 17 April 2015 at 11:37, Morten Rasmussen morten.rasmussen@arm.com wrote:
On Fri, Apr 17, 2015 at 03:34:30PM +0100, Ashwin Chaugule wrote:
On 16 April 2015 at 01:29, Michael Turquette mturquette@linaro.org wrote:
/*
* get_cpu_usage is called without locking the runqueues. This is the
* same behavior used by find_busiest_cpu in load_balance. We are
* willing to accept occasionally stale data here in exchange for
* lockless behavior.
*/
for_each_cpu(cpu, policy->cpus) {
usage = get_cpu_usage(cpu);
trace_printk("cpu = %d usage = %lu", cpu, usage);
if (usage > max_usage)
max_usage = usage;
}
trace_printk("max_usage = %lu", max_usage);
/* find the utilization threshold at which we scale up frequency */
index = cpufreq_frequency_table_get_index(policy, policy->cur);
/*
* converge towards max_usage. We want the lowest frequency whose
* capacity is >= to max_usage. In other words:
*
* find capacity == floor(usage)
*
* Sadly cpufreq freq tables are not guaranteed to be ordered by
* frequency...
*/
freq = policy->max;
cpufreq_for_each_entry(pos, policy->freq_table) {
cap = pos->frequency * SCHED_CAPACITY_SCALE /
policy->max;
if (max_usage < cap && pos->frequency < freq)
freq = pos->frequency;
trace_printk("cpu = %u max_usage = %lu cap = %lu \
table_freq = %u freq = %lu",
cpumask_first(policy->cpus), max_usage, cap,
pos->frequency, freq);
}
This code assumes all backend drivers will support a frequency table. I think this may not be always true (e.g. pcc-cpufreq.c which is already upstream or even the WIP CPPC driver). What do you think about detecting if the backend does not support a freq table, then just pass the max_usage down to the driver and let the driver handle it from there?
Ashwin, you are correct that this code assume a freq table. Just a bit of laziness on my part to get the code out there.
Unless you change the driver interface it has to be a frequency passed to the driver.
Sure, but the pcc-cpufreq driver doesn't export a freq table although it seemingly accepts freq requests. Not sure if there are other similar examples. Why not pass the next freq request proportional to the load like ondemand does and let the backend take care of snapping the request to a table if it supports it? That'll keep things consistent with the current design. (sorry if I misunderstood CPU usage. Still grokking it.)
Do you actually need to consider the OPP frequencies at all? It looks for the lowest frequency with enough capacity for max_usage. But, I don't think it is necessary to find a valid OPP frequency. __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_H) should be able handle that as long as we can provide it a minimum frequency (freq) which is sufficient for max_usage.
Can't we get away with just returning:
(max_usage * policy->max)/SCHED_CAPACITY_SCALE
and avoid having to look at the frequency table?
The 2014 sched-freq rfc had something like this. I switched to the freq table for a variety of reasons, some of which seemed important early on and are not important now.
But I still think it might be an optimization for the driver to use the table if it exists, instead of passing an arbitrary frequency which must get mapped to the table in the driver backend.
It isn't as simple as that though, some margin or threshold has to be added so we don't have to wait until max_usage == cap before we ask for a higher OPP. It takes ages to get there (100+ ms).
This isn't always true. First, I'd like to avoid a threshold if possible. I'm still not convinced it is necessary.
Secondly, for workloads that create new tasks and place them on the workqueue, we ramp up almost immediately because the load of the new task is maxed out be default (I hope I got that right).
In my testing, which mostly involves interactive scripts that I have written, I see near-instantaneous responses when I am idle and then I start some work.
Testing with a real-world use case would be great, especially something like Android.
Amit, can the backport stuff help us here? Is there an Android build that uses the eas 3.10 backport? Any testing using it?
Btw, I noted that __cpufreq_driver_target() is deprecated. Are you planning on using that for the CPPC driver? Based on my rather limited understanding of CPPC I would have guessed you would go with setpolicy() instead?
I saw that comment too, but I dont think all drivers have/can have a discretized freq table, so I dont see how that call can be removed entirely. For CPPC, setpolicy() was the initial approach with PID as the governor, but after some experiments and talking to Rafael, we found that using the target() method + ondemand is a better solution, at least initially.
I guess we can sort this bit out when the series is posted to LKML.
Regards, Mike
Regards, Ashwin.