Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86: CPU: Fix up "cpu MHz" in /proc/cpuinfo

Commit 890da9cf0983 (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: 890da9cf0983 (Revert "x86: do not use cpufreq_quick_get() for /proc/cpuinfo "cpu MHz"")
Cc: stable@kernel.org # 4.13 - together with 890da9cf0983
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Rafael J. Wysocki and committed by
Linus Torvalds
941f5f0f 5cb0512c

+11 -6
+1 -1
arch/x86/kernel/cpu/Makefile
··· 22 22 obj-y += rdrand.o 23 23 obj-y += match.o 24 24 obj-y += bugs.o 25 - obj-$(CONFIG_CPU_FREQ) += aperfmperf.o 25 + obj-y += aperfmperf.o 26 26 27 27 obj-$(CONFIG_PROC_FS) += proc.o 28 28 obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
+7 -4
arch/x86/kernel/cpu/aperfmperf.c
··· 42 42 s64 time_delta = ktime_ms_delta(now, s->time); 43 43 unsigned long flags; 44 44 45 - /* Don't bother re-computing within the cache threshold time. */ 46 - if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS) 47 - return; 48 - 49 45 local_irq_save(flags); 50 46 rdmsrl(MSR_IA32_APERF, aperf); 51 47 rdmsrl(MSR_IA32_MPERF, mperf); ··· 70 74 71 75 unsigned int arch_freq_get_on_cpu(int cpu) 72 76 { 77 + s64 time_delta; 73 78 unsigned int khz; 74 79 75 80 if (!cpu_khz) ··· 78 81 79 82 if (!static_cpu_has(X86_FEATURE_APERFMPERF)) 80 83 return 0; 84 + 85 + /* Don't bother re-computing within the cache threshold time. */ 86 + time_delta = ktime_ms_delta(ktime_get(), per_cpu(samples.time, cpu)); 87 + khz = per_cpu(samples.khz, cpu); 88 + if (khz && time_delta < APERFMPERF_CACHE_THRESHOLD_MS) 89 + return khz; 81 90 82 91 smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1); 83 92 khz = per_cpu(samples.khz, cpu);
+3 -1
arch/x86/kernel/cpu/proc.c
··· 78 78 seq_printf(m, "microcode\t: 0x%x\n", c->microcode); 79 79 80 80 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); 82 82 83 + if (!freq) 84 + freq = cpufreq_quick_get(cpu); 83 85 if (!freq) 84 86 freq = cpu_khz; 85 87 seq_printf(m, "cpu MHz\t\t: %u.%03u\n",