Merge branch 'for-next/cpufreq' into for-next/core
* for-next/cpufreq: arm64: topology: Do not warn on missing AMU in cpuhp_topology_online() arm64: topology: Handle AMU FIE setup on CPU hotplug cpufreq: Add new helper function returning cpufreq policy arm64: topology: Skip already covered CPUs when setting freq sourcemaster
commit
c2581836cc
|
|
@ -272,7 +272,7 @@ static void amu_fie_setup(const struct cpumask *cpus)
|
|||
|
||||
cpumask_or(amu_fie_cpus, amu_fie_cpus, cpus);
|
||||
|
||||
topology_set_scale_freq_source(&amu_sfd, amu_fie_cpus);
|
||||
topology_set_scale_freq_source(&amu_sfd, cpus);
|
||||
|
||||
pr_debug("CPUs[%*pbl]: counters will be used for FIE.",
|
||||
cpumask_pr_args(cpus));
|
||||
|
|
@ -284,7 +284,7 @@ static int init_amu_fie_callback(struct notifier_block *nb, unsigned long val,
|
|||
struct cpufreq_policy *policy = data;
|
||||
|
||||
if (val == CPUFREQ_CREATE_POLICY)
|
||||
amu_fie_setup(policy->related_cpus);
|
||||
amu_fie_setup(policy->cpus);
|
||||
|
||||
/*
|
||||
* We don't need to handle CPUFREQ_REMOVE_POLICY event as the AMU
|
||||
|
|
@ -303,10 +303,70 @@ static struct notifier_block init_amu_fie_notifier = {
|
|||
.notifier_call = init_amu_fie_callback,
|
||||
};
|
||||
|
||||
static int cpuhp_topology_online(unsigned int cpu)
|
||||
{
|
||||
struct cpufreq_policy *policy = cpufreq_cpu_policy(cpu);
|
||||
|
||||
/* Those are cheap checks */
|
||||
|
||||
/*
|
||||
* Skip this CPU if:
|
||||
* - it has no cpufreq policy assigned yet,
|
||||
* - no policy exists that spans CPUs with AMU counters, or
|
||||
* - it was already handled.
|
||||
*/
|
||||
if (unlikely(!policy) || !cpumask_available(amu_fie_cpus) ||
|
||||
cpumask_test_cpu(cpu, amu_fie_cpus))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Only proceed if all already-online CPUs in this policy
|
||||
* support AMU counters.
|
||||
*/
|
||||
if (unlikely(!cpumask_subset(policy->cpus, amu_fie_cpus)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If the new online CPU cannot pass this check, all the CPUs related to
|
||||
* the same policy should be clear from amu_fie_cpus mask, otherwise they
|
||||
* may use different source of the freq scale.
|
||||
*/
|
||||
if (!freq_counters_valid(cpu)) {
|
||||
topology_clear_scale_freq_source(SCALE_FREQ_SOURCE_ARCH,
|
||||
policy->related_cpus);
|
||||
cpumask_andnot(amu_fie_cpus, amu_fie_cpus, policy->related_cpus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpumask_set_cpu(cpu, amu_fie_cpus);
|
||||
|
||||
topology_set_scale_freq_source(&amu_sfd, cpumask_of(cpu));
|
||||
|
||||
pr_debug("CPU[%u]: counter will be used for FIE.", cpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init init_amu_fie(void)
|
||||
{
|
||||
return cpufreq_register_notifier(&init_amu_fie_notifier,
|
||||
int ret;
|
||||
|
||||
ret = cpufreq_register_notifier(&init_amu_fie_notifier,
|
||||
CPUFREQ_POLICY_NOTIFIER);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
|
||||
"arm64/topology:online",
|
||||
cpuhp_topology_online,
|
||||
NULL);
|
||||
if (ret < 0) {
|
||||
cpufreq_unregister_notifier(&init_amu_fie_notifier,
|
||||
CPUFREQ_POLICY_NOTIFIER);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(init_amu_fie);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,14 @@ EXPORT_PER_CPU_SYMBOL_GPL(capacity_freq_ref);
|
|||
|
||||
static bool supports_scale_freq_counters(const struct cpumask *cpus)
|
||||
{
|
||||
return cpumask_subset(cpus, &scale_freq_counters_mask);
|
||||
int i;
|
||||
|
||||
for_each_cpu(i, cpus) {
|
||||
if (cpumask_test_cpu(i, &scale_freq_counters_mask))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool topology_scale_freq_invariant(void)
|
||||
|
|
|
|||
|
|
@ -198,6 +198,12 @@ struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_cpu_get_raw);
|
||||
|
||||
struct cpufreq_policy *cpufreq_cpu_policy(unsigned int cpu)
|
||||
{
|
||||
return per_cpu(cpufreq_cpu_data, cpu);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_cpu_policy);
|
||||
|
||||
unsigned int cpufreq_generic_get(unsigned int cpu)
|
||||
{
|
||||
struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu);
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ struct cpufreq_freqs {
|
|||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu);
|
||||
struct cpufreq_policy *cpufreq_cpu_policy(unsigned int cpu);
|
||||
struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu);
|
||||
void cpufreq_cpu_put(struct cpufreq_policy *policy);
|
||||
#else
|
||||
|
|
@ -210,6 +211,10 @@ static inline struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline struct cpufreq_policy *cpufreq_cpu_policy(unsigned int cpu)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
|
||||
{
|
||||
return NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue