Skip to content

Commit 8a05c31

Browse files
committed
Merge branches 'pm-cpufreq-x86', 'pm-cpufreq-docs' and 'intel_pstate'
* pm-cpufreq-x86: cpufreq: x86: Make scaling_cur_freq behave more as expected * pm-cpufreq-docs: cpufreq: docs: Add missing cpuinfo_cur_freq description * intel_pstate: cpufreq: intel_pstate: Drop ->get from intel_pstate structure
4 parents 16f73eb + 4815d3c + c2e3af1 + 22baebd commit 8a05c31

File tree

3 files changed

+34
-22
lines changed

3 files changed

+34
-22
lines changed

Documentation/admin-guide/pm/cpufreq.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ are the following:
237237
This attribute is not present if the scaling driver in use does not
238238
support it.
239239

240+
``cpuinfo_cur_freq``
241+
Current frequency of the CPUs belonging to this policy as obtained from
242+
the hardware (in KHz).
243+
244+
This is expected to be the frequency the hardware actually runs at.
245+
If that frequency cannot be determined, this attribute should not
246+
be present.
247+
240248
``cpuinfo_max_freq``
241249
Maximum possible operating frequency the CPUs belonging to this policy
242250
can run at (in kHz).

arch/x86/kernel/cpu/aperfmperf.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,25 @@
88
* This file is licensed under GPLv2.
99
*/
1010

11-
#include <linux/jiffies.h>
11+
#include <linux/delay.h>
12+
#include <linux/ktime.h>
1213
#include <linux/math64.h>
1314
#include <linux/percpu.h>
1415
#include <linux/smp.h>
1516

1617
struct aperfmperf_sample {
1718
unsigned int khz;
18-
unsigned long jiffies;
19+
ktime_t time;
1920
u64 aperf;
2021
u64 mperf;
2122
};
2223

2324
static DEFINE_PER_CPU(struct aperfmperf_sample, samples);
2425

26+
#define APERFMPERF_CACHE_THRESHOLD_MS 10
27+
#define APERFMPERF_REFRESH_DELAY_MS 20
28+
#define APERFMPERF_STALE_THRESHOLD_MS 1000
29+
2530
/*
2631
* aperfmperf_snapshot_khz()
2732
* On the current CPU, snapshot APERF, MPERF, and jiffies
@@ -33,9 +38,11 @@ static void aperfmperf_snapshot_khz(void *dummy)
3338
u64 aperf, aperf_delta;
3439
u64 mperf, mperf_delta;
3540
struct aperfmperf_sample *s = this_cpu_ptr(&samples);
41+
ktime_t now = ktime_get();
42+
s64 time_delta = ktime_ms_delta(now, s->time);
3643

37-
/* Don't bother re-computing within 10 ms */
38-
if (time_before(jiffies, s->jiffies + HZ/100))
44+
/* Don't bother re-computing within the cache threshold time. */
45+
if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS)
3946
return;
4047

4148
rdmsrl(MSR_IA32_APERF, aperf);
@@ -51,29 +58,34 @@ static void aperfmperf_snapshot_khz(void *dummy)
5158
if (mperf_delta == 0)
5259
return;
5360

54-
/*
55-
* if (cpu_khz * aperf_delta) fits into ULLONG_MAX, then
56-
* khz = (cpu_khz * aperf_delta) / mperf_delta
57-
*/
58-
if (div64_u64(ULLONG_MAX, cpu_khz) > aperf_delta)
59-
s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
60-
else /* khz = aperf_delta / (mperf_delta / cpu_khz) */
61-
s->khz = div64_u64(aperf_delta,
62-
div64_u64(mperf_delta, cpu_khz));
63-
s->jiffies = jiffies;
61+
s->time = now;
6462
s->aperf = aperf;
6563
s->mperf = mperf;
64+
65+
/* If the previous iteration was too long ago, discard it. */
66+
if (time_delta > APERFMPERF_STALE_THRESHOLD_MS)
67+
s->khz = 0;
68+
else
69+
s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
6670
}
6771

6872
unsigned int arch_freq_get_on_cpu(int cpu)
6973
{
74+
unsigned int khz;
75+
7076
if (!cpu_khz)
7177
return 0;
7278

7379
if (!static_cpu_has(X86_FEATURE_APERFMPERF))
7480
return 0;
7581

7682
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
83+
khz = per_cpu(samples.khz, cpu);
84+
if (khz)
85+
return khz;
86+
87+
msleep(APERFMPERF_REFRESH_DELAY_MS);
88+
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
7789

7890
return per_cpu(samples.khz, cpu);
7991
}

drivers/cpufreq/intel_pstate.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,13 +1922,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
19221922
return 0;
19231923
}
19241924

1925-
static unsigned int intel_pstate_get(unsigned int cpu_num)
1926-
{
1927-
struct cpudata *cpu = all_cpu_data[cpu_num];
1928-
1929-
return cpu ? get_avg_frequency(cpu) : 0;
1930-
}
1931-
19321925
static void intel_pstate_set_update_util_hook(unsigned int cpu_num)
19331926
{
19341927
struct cpudata *cpu = all_cpu_data[cpu_num];
@@ -2169,7 +2162,6 @@ static struct cpufreq_driver intel_pstate = {
21692162
.setpolicy = intel_pstate_set_policy,
21702163
.suspend = intel_pstate_hwp_save_state,
21712164
.resume = intel_pstate_resume,
2172-
.get = intel_pstate_get,
21732165
.init = intel_pstate_cpu_init,
21742166
.exit = intel_pstate_cpu_exit,
21752167
.stop_cpu = intel_pstate_stop_cpu,

0 commit comments

Comments
 (0)