···246246 static_branch_enable(&amu_fie_key);247247 }248248249249+ /*250250+ * If the system is not fully invariant after AMU init, disable251251+ * partial use of counters for frequency invariance.252252+ */253253+ if (!topology_scale_freq_invariant())254254+ static_branch_disable(&amu_fie_key);255255+249256free_valid_mask:250257 free_cpumask_var(valid_cpus);251258···260253}261254late_initcall_sync(init_amu_fie);262255263263-bool arch_freq_counters_available(struct cpumask *cpus)256256+bool arch_freq_counters_available(const struct cpumask *cpus)264257{265258 return amu_freq_invariant() &&266259 cpumask_subset(cpus, amu_fie_cpus);
+11-2
drivers/base/arch_topology.c
···2121#include <linux/sched.h>2222#include <linux/smp.h>23232424-__weak bool arch_freq_counters_available(struct cpumask *cpus)2424+bool topology_scale_freq_invariant(void)2525+{2626+ return cpufreq_supports_freq_invariance() ||2727+ arch_freq_counters_available(cpu_online_mask);2828+}2929+3030+__weak bool arch_freq_counters_available(const struct cpumask *cpus)2531{2632 return false;2733}2834DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE;29353030-void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq,3636+void arch_set_freq_scale(const struct cpumask *cpus, unsigned long cur_freq,3137 unsigned long max_freq)3238{3339 unsigned long scale;3440 int i;4141+4242+ if (WARN_ON_ONCE(!cur_freq || !max_freq))4343+ return;35443645 /*3746 * If the use of counters for FIE is enabled, just return as we don't
+1-9
drivers/cpufreq/cpufreq-dt.c
···4040{4141 struct private_data *priv = policy->driver_data;4242 unsigned long freq = policy->freq_table[index].frequency;4343- int ret;44434545- ret = dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000);4646-4747- if (!ret) {4848- arch_set_freq_scale(policy->related_cpus, freq,4949- policy->cpuinfo.max_freq);5050- }5151-5252- return ret;4444+ return dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000);5345}54465547/*
+31-4
drivers/cpufreq/cpufreq.c
···6161static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);6262static DEFINE_RWLOCK(cpufreq_driver_lock);63636464+static DEFINE_STATIC_KEY_FALSE(cpufreq_freq_invariance);6565+bool cpufreq_supports_freq_invariance(void)6666+{6767+ return static_branch_likely(&cpufreq_freq_invariance);6868+}6969+6470/* Flag to suspend/resume CPUFreq governors */6571static bool cpufreq_suspended;6672···160154}161155EXPORT_SYMBOL_GPL(get_cpu_idle_time);162156163163-__weak void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq,164164- unsigned long max_freq)157157+__weak void arch_set_freq_scale(const struct cpumask *cpus,158158+ unsigned long cur_freq,159159+ unsigned long max_freq)165160{166161}167162EXPORT_SYMBOL_GPL(arch_set_freq_scale);···452445 return;453446454447 cpufreq_notify_post_transition(policy, freqs, transition_failed);448448+449449+ arch_set_freq_scale(policy->related_cpus,450450+ policy->cur,451451+ policy->cpuinfo.max_freq);455452456453 policy->transition_ongoing = false;457454 policy->transition_task = NULL;···20672056unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,20682057 unsigned int target_freq)20692058{20702070- target_freq = clamp_val(target_freq, policy->min, policy->max);20592059+ unsigned int freq;2071206020722072- return cpufreq_driver->fast_switch(policy, target_freq);20612061+ target_freq = clamp_val(target_freq, policy->min, policy->max);20622062+ freq = cpufreq_driver->fast_switch(policy, target_freq);20632063+20642064+ arch_set_freq_scale(policy->related_cpus, freq,20652065+ policy->cpuinfo.max_freq);20662066+20672067+ return freq;20732068}20742069EXPORT_SYMBOL_GPL(cpufreq_driver_fast_switch);20752070···27272710 cpufreq_driver = driver_data;27282711 write_unlock_irqrestore(&cpufreq_driver_lock, flags);2729271227132713+ /*27142714+ * Mark support for the scheduler's frequency invariance engine for27152715+ * drivers that implement target(), target_index() or fast_switch().27162716+ */27172717+ if (!cpufreq_driver->setpolicy) {27182718+ static_branch_enable_cpuslocked(&cpufreq_freq_invariance);27192719+ pr_debug("supports frequency invariance");27202720+ }27212721+27302722 if (driver_data->setpolicy)27312723 driver_data->flags |= CPUFREQ_CONST_LOOPS;27322724···28052779 cpus_read_lock();28062780 subsys_interface_unregister(&cpufreq_interface);28072781 remove_boost_sysfs_file();27822782+ static_branch_disable_cpuslocked(&cpufreq_freq_invariance);28082783 cpuhp_remove_state_nocalls_cpuslocked(hp_online);2809278428102785 write_lock_irqsave(&cpufreq_driver_lock, flags);
+1-8
drivers/cpufreq/qcom-cpufreq-hw.c
···8585 if (icc_scaling_enabled)8686 qcom_cpufreq_set_bw(policy, freq);87878888- arch_set_freq_scale(policy->related_cpus, freq,8989- policy->cpuinfo.max_freq);9088 return 0;9189}9290···111113{112114 void __iomem *perf_state_reg = policy->driver_data;113115 unsigned int index;114114- unsigned long freq;115116116117 index = policy->cached_resolved_idx;117118 writel_relaxed(index, perf_state_reg);118119119119- freq = policy->freq_table[index].frequency;120120- arch_set_freq_scale(policy->related_cpus, freq,121121- policy->cpuinfo.max_freq);122122-123123- return freq;120120+ return policy->freq_table[index].frequency;124121}125122126123static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,