Skip to content

Commit 941f5f0

Browse files
rafaeljwtorvalds
authored andcommitted
x86: CPU: Fix up "cpu MHz" in /proc/cpuinfo
Commit 890da9c (Revert "x86: do not use cpufreq_quick_get() for /proc/cpuinfo "cpu MHz"") is not sufficient to restore the previous behavior of "cpu MHz" in /proc/cpuinfo on x86 due to some changes made after the commit it has reverted. To address this, make the code in question use arch_freq_get_on_cpu() which also is used by cpufreq for reporting the current frequency of CPUs and since that function doesn't really depend on cpufreq in any way, drop the CONFIG_CPU_FREQ dependency for the object file containing it. Also refactor arch_freq_get_on_cpu() somewhat to avoid IPIs and return cached values right away if it is called very often over a short time (to prevent user space from triggering IPI storms through it). Fixes: 890da9c (Revert "x86: do not use cpufreq_quick_get() for /proc/cpuinfo "cpu MHz"") Cc: stable@kernel.org # 4.13 - together with 890da9c Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 5cb0512 commit 941f5f0

File tree

3 files changed

+11
-6
lines changed

3 files changed

+11
-6
lines changed

arch/x86/kernel/cpu/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ obj-y += common.o
2222
obj-y += rdrand.o
2323
obj-y += match.o
2424
obj-y += bugs.o
25-
obj-$(CONFIG_CPU_FREQ) += aperfmperf.o
25+
obj-y += aperfmperf.o
2626

2727
obj-$(CONFIG_PROC_FS) += proc.o
2828
obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o

arch/x86/kernel/cpu/aperfmperf.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ static void aperfmperf_snapshot_khz(void *dummy)
4242
s64 time_delta = ktime_ms_delta(now, s->time);
4343
unsigned long flags;
4444

45-
/* Don't bother re-computing within the cache threshold time. */
46-
if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS)
47-
return;
48-
4945
local_irq_save(flags);
5046
rdmsrl(MSR_IA32_APERF, aperf);
5147
rdmsrl(MSR_IA32_MPERF, mperf);
@@ -74,6 +70,7 @@ static void aperfmperf_snapshot_khz(void *dummy)
7470

7571
unsigned int arch_freq_get_on_cpu(int cpu)
7672
{
73+
s64 time_delta;
7774
unsigned int khz;
7875

7976
if (!cpu_khz)
@@ -82,6 +79,12 @@ unsigned int arch_freq_get_on_cpu(int cpu)
8279
if (!static_cpu_has(X86_FEATURE_APERFMPERF))
8380
return 0;
8481

82+
/* Don't bother re-computing within the cache threshold time. */
83+
time_delta = ktime_ms_delta(ktime_get(), per_cpu(samples.time, cpu));
84+
khz = per_cpu(samples.khz, cpu);
85+
if (khz && time_delta < APERFMPERF_CACHE_THRESHOLD_MS)
86+
return khz;
87+
8588
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
8689
khz = per_cpu(samples.khz, cpu);
8790
if (khz)

arch/x86/kernel/cpu/proc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
7878
seq_printf(m, "microcode\t: 0x%x\n", c->microcode);
7979

8080
if (cpu_has(c, X86_FEATURE_TSC)) {
81-
unsigned int freq = cpufreq_quick_get(cpu);
81+
unsigned int freq = arch_freq_get_on_cpu(cpu);
8282

83+
if (!freq)
84+
freq = cpufreq_quick_get(cpu);
8385
if (!freq)
8486
freq = cpu_khz;
8587
seq_printf(m, "cpu MHz\t\t: %u.%03u\n",

0 commit comments

Comments
 (0)