On 10/03/15 23:00, Mike Turquette wrote:
On Tue, Mar 10, 2015 at 3:10 AM, Juri Lelli juri.lelli@arm.com wrote:
Hi Mike,
On 10/03/15 01:38, Mike Turquette wrote:
Quoting Juri Lelli (2015-03-09 07:06:18)
We already have capacity information in the EAS energy model tables. Let's use it to both avoid duplication and achieve freq/uarch invariance.
Signed-off-by: Juri Lelli juri.lelli@arm.com
kernel/sched/energy_model.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/kernel/sched/energy_model.c b/kernel/sched/energy_model.c index 7fec5af..64bd50e 100644 --- a/kernel/sched/energy_model.c +++ b/kernel/sched/energy_model.c @@ -247,6 +247,8 @@ static void em_start(struct cpufreq_policy *policy) unsigned int capacity; struct em_data *em; struct cpufreq_frequency_table *pos;
struct sched_domain *sd;
struct sched_group_energy *sge = NULL; /* prepare per-policy private data */ em = kzalloc(sizeof(*em), GFP_KERNEL);
@@ -265,16 +267,35 @@ static void em_start(struct cpufreq_policy *policy) em->up_threshold = kcalloc(count, sizeof(unsigned int), GFP_KERNEL); em->down_threshold = kcalloc(count, sizeof(unsigned int), GFP_KERNEL);
cpufreq_for_each_entry(pos, policy->freq_table) {
/* FIXME capacity below is not scaled for uarch */
capacity = pos->frequency * SCHED_CAPACITY_SCALE / policy->max;
for_each_domain(cpumask_first(policy->cpus), sd)
if (!sd->child) {
+#ifdef CONFIG_SCHED_DEBUG
pr_debug("%s: using %s sched_group_energy\n",
__func__,
sd->name);
+#endif
sge = sd->groups->sge;
break;
}
if (!sge) {
pr_debug("%s: failed to access sched_group_energy\n",
__func__);
kfree(em->up_threshold);
kfree(em->down_threshold);
kfree(em);
return;
}
for (index = 0; index < sge->nr_cap_states; index++) {
/* capacity below is both freq and uarch scaled */
capacity = sge->cap_states[index].cap;
Hi Juri,
Thanks for sharing the patch. Is there a functional change in this patch? From what I can tell this is a different way of doing the same thing. Please let me know if I am wrong.
Yes, you are right, no functional change here. But I needed to create these tables using the energy model because the utilization signal we get from get_cpu_usage is both uarch and freq capped to the current capacity of the cpu. So the thresholds had to take this into account.
I had forgotten about the uarch invariance bit. I'll need to take that into account as well if building the threshold cap values from scratch.
However the thresholds at a certain capacity will always be less than that capacity (e.g. 20% or 80% of that frequency/capacity). So besides taking into account the uarch invariance was there another reason to pull the energy model cap state table in?
Nope. I just had to build the thresholds around the max capacity you can get at a certain OPP on a certain CPU.
Also, I'm trying to understand the full dependency on the energy model. I see get_cpu_usage is now used here. Assuming that we use the old code that uses the internal cpufreq frequency table (instead of the sge cap state table) then the only tangible dependency is on Vincent's V10 cpu capacity rework, correct? Put another way, you are not yet using any energy_diff stuff in the dvfs policy.
No energy_diff stuff in there. But you still got a dependency from the energy model tables to create the internal tables.
I'm not sure if we want to ever use energy_diff stuff in there, actually. We may want to be as general as possible, and just act on changes of the utilization signal of the various cpus.
For a first step I completely agree. But in the future I can imagine a scenario where we want to compare the energy cost of migrating a task from src_cpu to dst_cpu versus running src_cpu at a faster frequency.
Not sure I'm following you here. Isn't this up to the scheduler?
Best,
- Juri
Regards, Mike
Best,
- Juri
Thanks, Mike
em->up_threshold[index] = capacity * UP_THRESHOLD / 100; em->down_threshold[index] = capacity * DOWN_THRESHOLD / 100; pr_debug("%s: cpu = %u index = %d capacity = %u up = %u down = %u\n", __func__, cpumask_first(policy->cpus), index, capacity, em->up_threshold[index], em->down_threshold[index]);
index++; } /* init per-policy kthread */
-- 2.2.2