From e7d5459dfaf613799915e901189d296bdc7534f9 Mon Sep 17 00:00:00 2001 From: Dietmar Eggemann Date: Tue, 26 Sep 2017 17:41:07 +0100 Subject: cpufreq: provide default frequency-invariance setter function Frequency-invariant accounting support based on the ratio of current frequency and maximum supported frequency is an optional feature an arch can implement. Since there are cpufreq drivers (e.g. cpufreq-dt) which can be build for different arch's a default implementation of the frequency-invariance setter function arch_set_freq_scale() is needed. This default implementation is an empty weak function which will be overwritten by a strong function in case the arch provides one. The setter function passes the cpumask of related (to the frequency change) cpus (online and offline cpus), the (new) current frequency and the maximum supported frequency. Signed-off-by: Dietmar Eggemann Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- include/linux/cpufreq.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 537ff842ff73..28734ee185a7 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -919,6 +919,9 @@ static inline bool policy_has_boost_freq(struct cpufreq_policy *policy) extern unsigned int arch_freq_get_on_cpu(int cpu); +extern void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, + unsigned long max_freq); + /* the following are really really optional */ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs; -- cgit v1.2.3 From 0e27c567d1673137b06aa96bb7aef635fb657dee Mon Sep 17 00:00:00 2001 From: Dietmar Eggemann Date: Tue, 26 Sep 2017 17:41:10 +0100 Subject: drivers base/arch_topology: provide frequency-invariant accounting support Implements the arch-specific (arm and arm64) frequency-invariance setter function arch_set_freq_scale() which provides the following frequency scaling factor: current_freq(cpu) << SCHED_CAPACITY_SHIFT / max_supported_freq(cpu) One possible consumer of the frequency-invariance getter function topology_get_freq_scale() is the Per-Entity Load Tracking (PELT) mechanism of the task scheduler. Allow inlining of topology_get_freq_scale() into the task scheduler fast path (e.g. __update_load_avg_se()) by coding it as a static inline function in the arch topology header file. Signed-off-by: Dietmar Eggemann Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/base/arch_topology.c | 14 ++++++++++++++ include/linux/arch_topology.h | 9 +++++++++ 2 files changed, 23 insertions(+) (limited to 'include/linux') diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index e9bb368f32b3..416ec2f5211d 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -22,6 +22,20 @@ #include #include +DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE; + +void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, + unsigned long max_freq) +{ + unsigned long scale; + int i; + + scale = (cur_freq << SCHED_CAPACITY_SHIFT) / max_freq; + + for_each_cpu(i, cpus) + per_cpu(freq_scale, i) = scale; +} + static DEFINE_MUTEX(cpu_scale_mutex); static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h index 716ce587247e..f6e490312e4d 100644 --- a/include/linux/arch_topology.h +++ b/include/linux/arch_topology.h @@ -5,6 +5,7 @@ #define _LINUX_ARCH_TOPOLOGY_H_ #include +#include void topology_normalize_cpu_scale(void); @@ -16,4 +17,12 @@ unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu); void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity); +DECLARE_PER_CPU(unsigned long, freq_scale); + +static inline +unsigned long topology_get_freq_scale(struct sched_domain *sd, int cpu) +{ + return per_cpu(freq_scale, cpu); +} + #endif /* _LINUX_ARCH_TOPOLOGY_H_ */ -- cgit v1.2.3 From 8216f588b52b61ce36fc0080218e4730435e58b7 Mon Sep 17 00:00:00 2001 From: Dietmar Eggemann Date: Tue, 26 Sep 2017 17:41:11 +0100 Subject: drivers base/arch_topology: allow inlining cpu-invariant accounting support Allow inlining of topology_get_cpu_scale() into the task scheduler fast path (e.g. __update_load_avg_se()) by coding it as a static inline function in the arch topology header file. Signed-off-by: Dietmar Eggemann Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/base/arch_topology.c | 7 +------ include/linux/arch_topology.h | 8 +++++++- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 416ec2f5211d..aea0b9d521f6 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -37,12 +37,7 @@ void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, } static DEFINE_MUTEX(cpu_scale_mutex); -static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; - -unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu) -{ - return per_cpu(cpu_scale, cpu); -} +DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity) { diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h index f6e490312e4d..c189de3ef5df 100644 --- a/include/linux/arch_topology.h +++ b/include/linux/arch_topology.h @@ -12,8 +12,14 @@ void topology_normalize_cpu_scale(void); struct device_node; bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu); +DECLARE_PER_CPU(unsigned long, cpu_scale); + struct sched_domain; -unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu); +static inline +unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu) +{ + return per_cpu(cpu_scale, cpu); +} void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity); -- cgit v1.2.3