diff options
Diffstat (limited to 'meta-eas/recipes-kernel/linux/linux-renesas/0048-sched-Initialize-energy-data-structures.patch')
-rw-r--r-- | meta-eas/recipes-kernel/linux/linux-renesas/0048-sched-Initialize-energy-data-structures.patch | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/meta-eas/recipes-kernel/linux/linux-renesas/0048-sched-Initialize-energy-data-structures.patch b/meta-eas/recipes-kernel/linux/linux-renesas/0048-sched-Initialize-energy-data-structures.patch new file mode 100644 index 0000000..1107577 --- /dev/null +++ b/meta-eas/recipes-kernel/linux/linux-renesas/0048-sched-Initialize-energy-data-structures.patch @@ -0,0 +1,126 @@ +From cd9cfc061f16a3664fc374802e6c014602b0c94f Mon Sep 17 00:00:00 2001 +From: Dietmar Eggemann <dietmar.eggemann@arm.com> +Date: Fri, 14 Nov 2014 16:20:20 +0000 +Subject: [PATCH 48/92] sched: Initialize energy data structures + +The sched_group_energy (sge) pointer of the first sched_group (sg) in +the sched_domain (sd) is initialized to point to the appropriate (in +terms of sd level and cpu) sge data defined in the arch and so to the +correct part of the Energy Model (EM). + +Energy-aware scheduling allows that a system has only EM data up to a +certain sd level (so called highest energy aware balancing sd level). +A check in init_sched_energy() enforces that all sd's below this sd +level contain EM data. + +The 'int cpu' parameter of sched_domain_energy_f requires that +check_sched_energy_data() makes sure that all cpus spanned by a sg +are provisioned with the same EM data. + +This patch has also been tested with feature FORCE_SD_OVERLAP enabled. + +cc: Ingo Molnar <mingo@redhat.com> +cc: Peter Zijlstra <peterz@infradead.org> +Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com> +(cherry picked from commit 054c7ad511ad9e2b54e48d4e01d34be97fff104c) +Signed-off-by: Gaku Inami <gaku.inami.xw@bp.renesas.com> +--- + kernel/sched/core.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 71 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 209d2ea..083b318 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -6327,6 +6327,73 @@ static void init_sched_groups_capacity(int cpu, struct sched_domain *sd) + update_group_capacity(sd, cpu); + } + ++#define energy_eff(e, n) \ ++ ((e->cap_states[n].cap << SCHED_CAPACITY_SHIFT)/e->cap_states[n].power) ++ ++static void init_sched_groups_energy(int cpu, struct sched_domain *sd, ++ sched_domain_energy_f fn) ++{ ++ struct sched_group *sg = sd->groups; ++ const struct sched_group_energy *sge; ++ int i; ++ ++ if (!(fn && fn(cpu))) ++ return; ++ ++ if (cpu != group_balance_cpu(sg)) ++ return; ++ ++ if (sd->flags & SD_OVERLAP) { ++ pr_err("BUG: EAS does not support overlapping sd spans\n"); ++#ifdef CONFIG_SCHED_DEBUG ++ pr_err(" the %s domain has SD_OVERLAP set\n", sd->name); ++#endif ++ return; ++ } ++ ++ if (sd->child && !sd->child->groups->sge) { ++ pr_err("BUG: EAS setup borken for CPU%d\n", cpu); ++#ifdef CONFIG_SCHED_DEBUG ++ pr_err(" energy data on %s but not on %s domain\n", ++ sd->name, sd->child->name); ++#endif ++ return; ++ } ++ ++ sge = fn(cpu); ++ ++ /* ++ * Check that the per-cpu provided sd energy data is consistent for all ++ * cpus within the mask. ++ */ ++ if (cpumask_weight(sched_group_cpus(sg)) > 1) { ++ struct cpumask mask; ++ ++ cpumask_xor(&mask, sched_group_cpus(sg), get_cpu_mask(cpu)); ++ ++ for_each_cpu(i, &mask) ++ BUG_ON(sge != fn(i)); ++ } ++ ++ /* Check that energy efficiency (capacity/power) is monotonically ++ * decreasing in the capacity state vector with higher indexes ++ */ ++ for (i = 0; i < (sge->nr_cap_states - 1); i++) { ++ if (energy_eff(sge, i) > energy_eff(sge, i+1)) ++ continue; ++#ifdef CONFIG_SCHED_DEBUG ++ pr_warn("WARN: cpu=%d, domain=%s: incr. energy eff %lu[%d]->%lu[%d]\n", ++ cpu, sd->name, energy_eff(sge, i), i, ++ energy_eff(sge, i+1), i+1); ++#else ++ pr_warn("WARN: cpu=%d: incr. energy eff %lu[%d]->%lu[%d]\n", ++ cpu, energy_eff(sge, i), i, energy_eff(sge, i+1), i+1); ++#endif ++ } ++ ++ sd->groups->sge = fn(cpu); ++} ++ + /* + * Initializers for schedule domains + * Non-inlined to reduce accumulated stack pressure in build_sched_domains() +@@ -7052,10 +7119,13 @@ static int build_sched_domains(const struct cpumask *cpu_map, + + /* Calculate CPU capacity for physical packages and nodes */ + for (i = nr_cpumask_bits-1; i >= 0; i--) { ++ struct sched_domain_topology_level *tl = sched_domain_topology; ++ + if (!cpumask_test_cpu(i, cpu_map)) + continue; + +- for (sd = *per_cpu_ptr(d.sd, i); sd; sd = sd->parent) { ++ for (sd = *per_cpu_ptr(d.sd, i); sd; sd = sd->parent, tl++) { ++ init_sched_groups_energy(i, sd, tl->energy); + claim_allocations(i, sd); + init_sched_groups_capacity(i, sd); + } +-- +1.9.1 + |