summaryrefslogtreecommitdiffstats
path: root/meta-eas/recipes-kernel/linux/linux-renesas/0043-arm-Update-SD_ASYM_CPUCAPACITY-topology-flag-when-cp.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-eas/recipes-kernel/linux/linux-renesas/0043-arm-Update-SD_ASYM_CPUCAPACITY-topology-flag-when-cp.patch')
-rw-r--r--meta-eas/recipes-kernel/linux/linux-renesas/0043-arm-Update-SD_ASYM_CPUCAPACITY-topology-flag-when-cp.patch151
1 files changed, 151 insertions, 0 deletions
diff --git a/meta-eas/recipes-kernel/linux/linux-renesas/0043-arm-Update-SD_ASYM_CPUCAPACITY-topology-flag-when-cp.patch b/meta-eas/recipes-kernel/linux/linux-renesas/0043-arm-Update-SD_ASYM_CPUCAPACITY-topology-flag-when-cp.patch
new file mode 100644
index 0000000..6781716
--- /dev/null
+++ b/meta-eas/recipes-kernel/linux/linux-renesas/0043-arm-Update-SD_ASYM_CPUCAPACITY-topology-flag-when-cp.patch
@@ -0,0 +1,151 @@
+From 82ae3c283c44fb74536b33dfeb3f23e228af869f Mon Sep 17 00:00:00 2001
+From: Morten Rasmussen <morten.rasmussen@arm.com>
+Date: Wed, 22 Jun 2016 10:58:17 +0100
+Subject: [PATCH 43/92] arm: Update SD_ASYM_CPUCAPACITY topology flag when cpu
+ capacity is changed
+
+When cpu capacity information is provided through DT or sysfs we might
+not know if the system has asymmetric cpu capacities when the system
+topology information is initially passed to the scheduler. We therefore
+have to enforce a rebuild of the sched_domain hierarchy if we later
+discover that the flag was initially set wrong.
+
+It is mainly an issue for systems with same type of cores (dmips/mhz)
+but different max frequencies, and asymmetric cpu capacity systems where
+cpu capacity is not provided by DT but set through sysfs later.
+
+cc: Russell King <linux@armlinux.org.uk>
+
+Signed-off-by: Morten Rasmussen <morten.rasmussen@arm.com>
+(cherry picked from commit d02bb26e525bcbeb3c91345c4ee2a1fe1ca11e48)
+Signed-off-by: Gaku Inami <gaku.inami.xw@bp.renesas.com>
+---
+ arch/arm/kernel/topology.c | 39 +++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 37 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
+index 69fb4b6..4d94639 100644
+--- a/arch/arm/kernel/topology.c
++++ b/arch/arm/kernel/topology.c
+@@ -22,6 +22,7 @@
+ #include <linux/sched.h>
+ #include <linux/slab.h>
+ #include <linux/cpufreq.h>
++#include <linux/cpuset.h>
+
+ #include <asm/cputype.h>
+ #include <asm/topology.h>
+@@ -43,6 +44,8 @@
+ */
+ static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
+ static DEFINE_MUTEX(cpu_scale_mutex);
++static bool asym_cpucap;
++static bool update_flags;
+
+ unsigned long scale_cpu_capacity(struct sched_domain *sd, int cpu)
+ {
+@@ -54,6 +57,14 @@ static void set_capacity_scale(unsigned int cpu, unsigned long capacity)
+ per_cpu(cpu_scale, cpu) = capacity;
+ }
+
++static void update_sched_flags(void)
++{
++ update_flags = true;
++ rebuild_sched_domains();
++ update_flags = false;
++ pr_debug("cpu_capacity: Rebuilt sched_domain hierarchy.\n");
++}
++
+ #ifdef CONFIG_PROC_SYSCTL
+ #include <asm/cpu.h>
+ #include <linux/string.h>
+@@ -83,6 +94,7 @@ static ssize_t store_cpu_capacity(struct device *dev,
+
+ if (count) {
+ char *p = (char *) buf;
++ bool asym = false;
+
+ ret = kstrtoul(p, 0, &new_capacity);
+ if (ret)
+@@ -93,6 +105,17 @@ static ssize_t store_cpu_capacity(struct device *dev,
+ mutex_lock(&cpu_scale_mutex);
+ for_each_cpu(i, &cpu_topology[this_cpu].core_sibling)
+ set_capacity_scale(i, new_capacity);
++
++ for_each_possible_cpu(i) {
++ if (per_cpu(cpu_scale, i) != new_capacity)
++ asym = true;
++ }
++
++ if (asym != asym_cpucap) {
++ asym_cpucap = asym;
++ update_sched_flags();
++ }
++
+ mutex_unlock(&cpu_scale_mutex);
+ }
+
+@@ -154,7 +177,6 @@ struct cpu_efficiency {
+ static u32 *raw_capacity;
+ static bool cap_parsing_failed;
+ static u32 capacity_scale;
+-static bool asym_cpucap;
+
+ static int __init parse_cpu_capacity(struct device_node *cpu_node, int cpu)
+ {
+@@ -199,6 +221,7 @@ static void normalize_cpu_capacity(void)
+ {
+ u64 capacity;
+ int cpu;
++ bool asym = false;
+
+ if (!raw_capacity || cap_parsing_failed)
+ return;
+@@ -212,9 +235,12 @@ static void normalize_cpu_capacity(void)
+ pr_debug("cpu_capacity: CPU%d cpu_capacity=%lu\n",
+ cpu, arch_scale_cpu_capacity(NULL, cpu));
+ if (capacity < capacity_scale)
+- asym_cpucap = true;
++ asym = true;
+ }
+ mutex_unlock(&cpu_scale_mutex);
++
++ if (asym != asym_cpucap)
++ asym_cpucap = asym;
+ }
+
+ #ifdef CONFIG_CPU_FREQ
+@@ -232,6 +258,7 @@ static void normalize_cpu_capacity(void)
+ {
+ struct cpufreq_policy *policy = data;
+ int cpu;
++ bool asym;
+
+ if (cap_parsing_done)
+ return 0;
+@@ -254,7 +281,10 @@ static void normalize_cpu_capacity(void)
+ }
+ if (cpumask_empty(cpus_to_visit)) {
+ if (!cap_parsing_failed) {
++ asym = asym_cpucap;
+ normalize_cpu_capacity();
++ if (asym != asym_cpucap)
++ update_sched_flags();
+ kfree(raw_capacity);
+ pr_debug("cpu_capacity: parsing done");
+ } else {
+@@ -502,6 +532,11 @@ static void update_siblings_masks(unsigned int cpuid)
+ smp_wmb();
+ }
+
++int arch_update_cpu_topology(void)
++{
++ return update_flags ? 1 : 0;
++}
++
+ /*
+ * store_cpu_topology is called at boot when only one cpu is running
+ * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
+--
+1.9.1
+