Skip to content

Commit fccd2f0

Browse files
committed
Merge back cpufreq material for 5.10.
2 parents fc7d175 + 15e5d5b commit fccd2f0

12 files changed

Lines changed: 68 additions & 50 deletions

File tree

arch/arm/include/asm/topology.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
/* Replace task scheduler's default frequency-invariant accounting */
1111
#define arch_scale_freq_capacity topology_get_freq_scale
12+
#define arch_scale_freq_invariant topology_scale_freq_invariant
1213

1314
/* Replace task scheduler's default cpu-invariant accounting */
1415
#define arch_scale_cpu_capacity topology_get_cpu_scale

arch/arm64/include/asm/topology.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ void topology_scale_freq_tick(void);
2727

2828
/* Replace task scheduler's default frequency-invariant accounting */
2929
#define arch_scale_freq_capacity topology_get_freq_scale
30+
#define arch_scale_freq_invariant topology_scale_freq_invariant
3031

3132
/* Replace task scheduler's default cpu-invariant accounting */
3233
#define arch_scale_cpu_capacity topology_get_cpu_scale

arch/arm64/kernel/topology.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,14 +246,21 @@ static int __init init_amu_fie(void)
246246
static_branch_enable(&amu_fie_key);
247247
}
248248

249+
/*
250+
* If the system is not fully invariant after AMU init, disable
251+
* partial use of counters for frequency invariance.
252+
*/
253+
if (!topology_scale_freq_invariant())
254+
static_branch_disable(&amu_fie_key);
255+
249256
free_valid_mask:
250257
free_cpumask_var(valid_cpus);
251258

252259
return ret;
253260
}
254261
late_initcall_sync(init_amu_fie);
255262

256-
bool arch_freq_counters_available(struct cpumask *cpus)
263+
bool arch_freq_counters_available(const struct cpumask *cpus)
257264
{
258265
return amu_freq_invariant() &&
259266
cpumask_subset(cpus, amu_fie_cpus);

drivers/base/arch_topology.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,27 @@
2121
#include <linux/sched.h>
2222
#include <linux/smp.h>
2323

24-
__weak bool arch_freq_counters_available(struct cpumask *cpus)
24+
bool topology_scale_freq_invariant(void)
25+
{
26+
return cpufreq_supports_freq_invariance() ||
27+
arch_freq_counters_available(cpu_online_mask);
28+
}
29+
30+
__weak bool arch_freq_counters_available(const struct cpumask *cpus)
2531
{
2632
return false;
2733
}
2834
DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE;
2935

30-
void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq,
36+
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;
3541

42+
if (WARN_ON_ONCE(!cur_freq || !max_freq))
43+
return;
44+
3645
/*
3746
* If the use of counters for FIE is enabled, just return as we don't
3847
* want to update the scale factor with information from CPUFREQ.

drivers/cpufreq/cpufreq-dt.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,8 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
4040
{
4141
struct private_data *priv = policy->driver_data;
4242
unsigned long freq = policy->freq_table[index].frequency;
43-
int ret;
44-
45-
ret = dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000);
4643

47-
if (!ret) {
48-
arch_set_freq_scale(policy->related_cpus, freq,
49-
policy->cpuinfo.max_freq);
50-
}
51-
52-
return ret;
44+
return dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000);
5345
}
5446

5547
/*

drivers/cpufreq/cpufreq.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ static struct cpufreq_driver *cpufreq_driver;
6161
static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
6262
static DEFINE_RWLOCK(cpufreq_driver_lock);
6363

64+
static DEFINE_STATIC_KEY_FALSE(cpufreq_freq_invariance);
65+
bool cpufreq_supports_freq_invariance(void)
66+
{
67+
return static_branch_likely(&cpufreq_freq_invariance);
68+
}
69+
6470
/* Flag to suspend/resume CPUFreq governors */
6571
static bool cpufreq_suspended;
6672

@@ -154,8 +160,9 @@ u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
154160
}
155161
EXPORT_SYMBOL_GPL(get_cpu_idle_time);
156162

157-
__weak void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq,
158-
unsigned long max_freq)
163+
__weak void arch_set_freq_scale(const struct cpumask *cpus,
164+
unsigned long cur_freq,
165+
unsigned long max_freq)
159166
{
160167
}
161168
EXPORT_SYMBOL_GPL(arch_set_freq_scale);
@@ -446,6 +453,10 @@ void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
446453

447454
cpufreq_notify_post_transition(policy, freqs, transition_failed);
448455

456+
arch_set_freq_scale(policy->related_cpus,
457+
policy->cur,
458+
policy->cpuinfo.max_freq);
459+
449460
policy->transition_ongoing = false;
450461
policy->transition_task = NULL;
451462

@@ -2056,9 +2067,15 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
20562067
unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,
20572068
unsigned int target_freq)
20582069
{
2070+
unsigned int freq;
2071+
20592072
target_freq = clamp_val(target_freq, policy->min, policy->max);
2073+
freq = cpufreq_driver->fast_switch(policy, target_freq);
20602074

2061-
return cpufreq_driver->fast_switch(policy, target_freq);
2075+
arch_set_freq_scale(policy->related_cpus, freq,
2076+
policy->cpuinfo.max_freq);
2077+
2078+
return freq;
20622079
}
20632080
EXPORT_SYMBOL_GPL(cpufreq_driver_fast_switch);
20642081

@@ -2710,6 +2727,15 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
27102727
cpufreq_driver = driver_data;
27112728
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
27122729

2730+
/*
2731+
* Mark support for the scheduler's frequency invariance engine for
2732+
* drivers that implement target(), target_index() or fast_switch().
2733+
*/
2734+
if (!cpufreq_driver->setpolicy) {
2735+
static_branch_enable_cpuslocked(&cpufreq_freq_invariance);
2736+
pr_debug("supports frequency invariance");
2737+
}
2738+
27132739
if (driver_data->setpolicy)
27142740
driver_data->flags |= CPUFREQ_CONST_LOOPS;
27152741

@@ -2779,6 +2805,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
27792805
cpus_read_lock();
27802806
subsys_interface_unregister(&cpufreq_interface);
27812807
remove_boost_sysfs_file();
2808+
static_branch_disable_cpuslocked(&cpufreq_freq_invariance);
27822809
cpuhp_remove_state_nocalls_cpuslocked(hp_online);
27832810

27842811
write_lock_irqsave(&cpufreq_driver_lock, flags);

drivers/cpufreq/qcom-cpufreq-hw.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
8585
if (icc_scaling_enabled)
8686
qcom_cpufreq_set_bw(policy, freq);
8787

88-
arch_set_freq_scale(policy->related_cpus, freq,
89-
policy->cpuinfo.max_freq);
9088
return 0;
9189
}
9290

@@ -113,16 +111,11 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
113111
{
114112
void __iomem *perf_state_reg = policy->driver_data;
115113
unsigned int index;
116-
unsigned long freq;
117114

118115
index = policy->cached_resolved_idx;
119116
writel_relaxed(index, perf_state_reg);
120117

121-
freq = policy->freq_table[index].frequency;
122-
arch_set_freq_scale(policy->related_cpus, freq,
123-
policy->cpuinfo.max_freq);
124-
125-
return freq;
118+
return policy->freq_table[index].frequency;
126119
}
127120

128121
static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,

drivers/cpufreq/scmi-cpufreq.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,11 @@ static unsigned int scmi_cpufreq_get_rate(unsigned int cpu)
4848
static int
4949
scmi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
5050
{
51-
int ret;
5251
struct scmi_data *priv = policy->driver_data;
5352
struct scmi_perf_ops *perf_ops = handle->perf_ops;
5453
u64 freq = policy->freq_table[index].frequency;
5554

56-
ret = perf_ops->freq_set(handle, priv->domain_id, freq * 1000, false);
57-
if (!ret)
58-
arch_set_freq_scale(policy->related_cpus, freq,
59-
policy->cpuinfo.max_freq);
60-
return ret;
55+
return perf_ops->freq_set(handle, priv->domain_id, freq * 1000, false);
6156
}
6257

6358
static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
@@ -67,11 +62,8 @@ static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
6762
struct scmi_perf_ops *perf_ops = handle->perf_ops;
6863

6964
if (!perf_ops->freq_set(handle, priv->domain_id,
70-
target_freq * 1000, true)) {
71-
arch_set_freq_scale(policy->related_cpus, target_freq,
72-
policy->cpuinfo.max_freq);
65+
target_freq * 1000, true))
7366
return target_freq;
74-
}
7567

7668
return 0;
7769
}

drivers/cpufreq/scpi-cpufreq.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ static unsigned int scpi_cpufreq_get_rate(unsigned int cpu)
4747
static int
4848
scpi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
4949
{
50-
unsigned long freq = policy->freq_table[index].frequency;
50+
u64 rate = policy->freq_table[index].frequency * 1000;
5151
struct scpi_data *priv = policy->driver_data;
52-
u64 rate = freq * 1000;
5352
int ret;
5453

5554
ret = clk_set_rate(priv->clk, rate);
@@ -60,9 +59,6 @@ scpi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
6059
if (clk_get_rate(priv->clk) != rate)
6160
return -EIO;
6261

63-
arch_set_freq_scale(policy->related_cpus, freq,
64-
policy->cpuinfo.max_freq);
65-
6662
return 0;
6763
}
6864

drivers/cpufreq/vexpress-spc-cpufreq.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ static int ve_spc_cpufreq_set_target(struct cpufreq_policy *policy,
182182
{
183183
u32 cpu = policy->cpu, cur_cluster, new_cluster, actual_cluster;
184184
unsigned int freqs_new;
185-
int ret;
186185

187186
cur_cluster = cpu_to_cluster(cpu);
188187
new_cluster = actual_cluster = per_cpu(physical_cluster, cpu);
@@ -197,15 +196,8 @@ static int ve_spc_cpufreq_set_target(struct cpufreq_policy *policy,
197196
new_cluster = A15_CLUSTER;
198197
}
199198

200-
ret = ve_spc_cpufreq_set_rate(cpu, actual_cluster, new_cluster,
201-
freqs_new);
202-
203-
if (!ret) {
204-
arch_set_freq_scale(policy->related_cpus, freqs_new,
205-
policy->cpuinfo.max_freq);
206-
}
207-
208-
return ret;
199+
return ve_spc_cpufreq_set_rate(cpu, actual_cluster, new_cluster,
200+
freqs_new);
209201
}
210202

211203
static inline u32 get_table_count(struct cpufreq_frequency_table *table)

0 commit comments

Comments
 (0)