From 4ac03df1e16b160b0630c38661eb7fc19e324912 Mon Sep 17 00:00:00 2001 From: Srivatsa Vaddagiri Date: Mon, 31 Mar 2014 19:42:27 -0700 Subject: [PATCH 1/2] arm: topology: Define arch_get_cpu_efficiency() API for scheduler On a HMP system, scheduler needs to know efficiency factor (instructions-per-cycle) for various cpus. This is so that scheduler can estimate bandwidth consumption of tasks on each cpu, based on their efficiency factor. This patch defines arch_get_cpu_efficiency() API in ARM32 architecture. It depends on hard-coded "efficiency" factor for various cpu types (available in 'table_efficiency' data structure) and device-tree providing information on cpu-type for every cpu. Change-Id: I561bace8a813a35a9fc624fca4861c5b1109b69b Signed-off-by: Srivatsa Vaddagiri Signed-off-by: Syed Rameez Mustafa Signed-off-by: Pavankumar Kondeti --- arch/arm/kernel/topology.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 598323a1842e..9e7ed5c322f4 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -190,6 +190,13 @@ static int __init parse_cluster(struct device_node *cluster, int depth) return 0; } +static DEFINE_PER_CPU(unsigned long, cpu_efficiency) = SCHED_CAPACITY_SCALE; + +unsigned long arch_get_cpu_efficiency(int cpu) +{ + return per_cpu(cpu_efficiency, cpu); +} + #ifdef CONFIG_OF struct cpu_efficiency { const char *compatible; @@ -281,6 +288,8 @@ static int __init parse_dt_topology(void) if (cpu_eff->compatible == NULL) continue; + per_cpu(cpu_efficiency, cpu) = cpu_eff->efficiency; + rate = of_get_property(cn, "clock-frequency", &len); if (!rate || len != 4) { pr_err("%s missing clock-frequency property\n", From e91d6ecf73e9866337787bee54afbbfdbd7d9094 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Thu, 7 May 2015 17:14:48 +0530 Subject: [PATCH 2/2] arm: topology: Allow specifying the CPU efficiency from device tree The efficiency of a CPU can vary across SoCs depending on the cache size, bus interconnect frequencies etc. Allow specifying this from the device tree. This value overrides the default values hardcoded in the efficiency table. Change-Id: If2885675ce3d7b43c3b2568fe1e29a76f48a5c3d Signed-off-by: Pavankumar Kondeti --- arch/arm/kernel/topology.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 9e7ed5c322f4..e683d147816c 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -273,6 +273,7 @@ static int __init parse_dt_topology(void) for_each_possible_cpu(cpu) { const u32 *rate; int len; + u32 efficiency; /* too early to use cpu->of_node */ cn = of_get_cpu_node(cpu, NULL); @@ -281,14 +282,26 @@ static int __init parse_dt_topology(void) continue; } - for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++) - if (of_device_is_compatible(cn, cpu_eff->compatible)) - break; + /* + * The CPU efficiency value passed from the device tree + * overrides the value defined in the table_efficiency[] + */ + if (of_property_read_u32(cn, "efficiency", &efficiency) < 0) { - if (cpu_eff->compatible == NULL) - continue; + for (cpu_eff = table_efficiency; + cpu_eff->compatible; cpu_eff++) - per_cpu(cpu_efficiency, cpu) = cpu_eff->efficiency; + if (of_device_is_compatible(cn, + cpu_eff->compatible)) + break; + + if (cpu_eff->compatible == NULL) + continue; + + efficiency = cpu_eff->efficiency; + } + + per_cpu(cpu_efficiency, cpu) = efficiency; rate = of_get_property(cn, "clock-frequency", &len); if (!rate || len != 4) { @@ -297,7 +310,7 @@ static int __init parse_dt_topology(void) continue; } - capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency; + capacity = ((be32_to_cpup(rate)) >> 20) * efficiency; /* Save min capacity of the system */ if (capacity < min_capacity)