[PATCH] drivers base/arch_topology: enable cpufreq transistion notifier based FIE only for slow frequency switching

From: Dietmar Eggemann
Date: Wed Jun 21 2017 - 09:53:26 EST


Fast frequency switching is incompatible with cpufreq transition
notifiers.

Enable the cpufreq transition notifier based Frequency Invariance Engine
(FIE) only in case there are no cpufreq policies able to use fast
frequency switching.

Currently there are no cpufreq drivers for arm/arm64 which support fast
frequency switching. In case such a driver will appear the FEI
topology_get_freq_scale() has to be extended to provide frequency
invariance based on something else than cpufreq transition notifiers,
e.g. performance counters.

Signed-off-by: Dietmar Eggemann <dietmar.eggemann@xxxxxxx>
---
drivers/base/arch_topology.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index c2539dc584d5..bd14c5e81f63 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -171,6 +171,7 @@ static bool cap_parsing_done;
static void parsing_done_workfn(struct work_struct *work);
static DECLARE_WORK(parsing_done_work, parsing_done_workfn);
static DEFINE_PER_CPU(unsigned long, max_freq);
+static bool enable_freq_inv = true;

static int
init_cpu_capacity_callback(struct notifier_block *nb,
@@ -199,6 +200,8 @@ init_cpu_capacity_callback(struct notifier_block *nb,
policy->cpuinfo.max_freq / 1000UL;
capacity_scale = max(raw_capacity[cpu], capacity_scale);
}
+ if (policy->fast_switch_possible)
+ enable_freq_inv = false;
if (cpumask_empty(cpus_to_visit)) {
if (!cap_parsing_failed) {
topology_normalize_cpu_scale();
@@ -268,21 +271,23 @@ static int __init register_cpufreq_notifier(void)
ret = cpufreq_register_notifier(&init_cpu_capacity_notifier,
CPUFREQ_POLICY_NOTIFIER);

- if (ret) {
+ if (ret)
free_cpumask_var(cpus_to_visit);
- return ret;
- }

- return cpufreq_register_notifier(&set_freq_scale_notifier,
- CPUFREQ_TRANSITION_NOTIFIER);
+ return ret;
}
core_initcall(register_cpufreq_notifier);

static void parsing_done_workfn(struct work_struct *work)
{
+
free_cpumask_var(cpus_to_visit);
cpufreq_unregister_notifier(&init_cpu_capacity_notifier,
CPUFREQ_POLICY_NOTIFIER);
+
+ if (enable_freq_inv)
+ cpufreq_register_notifier(&set_freq_scale_notifier,
+ CPUFREQ_TRANSITION_NOTIFIER);
}

#else
--
2.11.0