lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 20 Oct 2020 17:44:39 +0200
From:   Redha Gouicem <redha.gouicem@...il.com>
To:     unlisted-recipients:; (no To-header on input)
Cc:     julien.sopena@...6.fr, julia.lawall@...ia.fr,
        gilles.muller@...ia.fr, carverdamien@...il.com,
        jean-pierre.lozi@...cle.com, baptiste.lepers@...ney.edu.au,
        nicolas.palix@...v-grenoble-alpes.fr,
        willy.zwaenepoel@...ney.edu.au,
        Redha Gouicem <redha.gouicem@...il.com>,
        Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
        x86@...nel.org, "H. Peter Anvin" <hpa@...or.com>,
        "Rafael J. Wysocki" <rjw@...ysocki.net>,
        Viresh Kumar <viresh.kumar@...aro.org>,
        Peter Zijlstra <peterz@...radead.org>,
        Juri Lelli <juri.lelli@...hat.com>,
        Vincent Guittot <vincent.guittot@...aro.org>,
        Dietmar Eggemann <dietmar.eggemann@....com>,
        Steven Rostedt <rostedt@...dmis.org>,
        Ben Segall <bsegall@...gle.com>, Mel Gorman <mgorman@...e.de>,
        Daniel Bristot de Oliveira <bristot@...hat.com>,
        Luis Chamberlain <mcgrof@...nel.org>,
        Kees Cook <keescook@...omium.org>,
        Iurii Zaikin <yzaikin@...gle.com>,
        "Guilherme G. Piccoli" <gpiccoli@...onical.com>,
        Al Viro <viro@...iv.linux.org.uk>,
        Qais Yousef <qais.yousef@....com>,
        linux-kernel@...r.kernel.org, linux-pm@...r.kernel.org,
        linux-fsdevel@...r.kernel.org
Subject: [PATCH 1/3] cpufreq: x86: allow external frequency measures

Allow other subsystems to query the current frequency from the CPU without
affecting the cached value of cpufreq. The subsystems doing this will need
to maintain their own version of struct aperfmperf_sample.

This is useful if you need to query frequency more frequently than
APERFMPERF_CACHE_THRESHOLD_MS but don't want to mess with the current
caching behavior.

Even though querying too frequently may render the measures inaccurate, it
is still useful if your subsystem tolerates this inaccuracy.

Co-developed-by: Damien Carver <carverdamien@...il.com>
Signed-off-by: Damien Carver <carverdamien@...il.com>
Signed-off-by: Redha Gouicem <redha.gouicem@...il.com>
---
 arch/x86/kernel/cpu/aperfmperf.c | 31 +++++++++++++++++++++++++++----
 drivers/cpufreq/cpufreq.c        |  5 +++++
 include/linux/cpufreq.h          |  1 +
 3 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
index e2f319dc992d..c3be81d689f4 100644
--- a/arch/x86/kernel/cpu/aperfmperf.c
+++ b/arch/x86/kernel/cpu/aperfmperf.c
@@ -36,11 +36,11 @@ static DEFINE_PER_CPU(struct aperfmperf_sample, samples);
  * unless we already did it within 10ms
  * calculate kHz, save snapshot
  */
-static void aperfmperf_snapshot_khz(void *dummy)
+static void aperfmperf_snapshot_khz(void *prev_sample)
 {
 	u64 aperf, aperf_delta;
 	u64 mperf, mperf_delta;
-	struct aperfmperf_sample *s = this_cpu_ptr(&samples);
+	struct aperfmperf_sample *s = prev_sample;
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -72,7 +72,8 @@ static bool aperfmperf_snapshot_cpu(int cpu, ktime_t now, bool wait)
 	if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS)
 		return true;
 
-	smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, wait);
+	smp_call_function_single(cpu, aperfmperf_snapshot_khz,
+				 per_cpu_ptr(&samples, cpu), wait);
 
 	/* Return false if the previous iteration was too long ago. */
 	return time_delta <= APERFMPERF_STALE_THRESHOLD_MS;
@@ -131,7 +132,29 @@ unsigned int arch_freq_get_on_cpu(int cpu)
 		return per_cpu(samples.khz, cpu);
 
 	msleep(APERFMPERF_REFRESH_DELAY_MS);
-	smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
+	smp_call_function_single(cpu, aperfmperf_snapshot_khz,
+				 per_cpu_ptr(&samples, cpu), 1);
 
 	return per_cpu(samples.khz, cpu);
 }
+
+unsigned int arch_freq_get_on_cpu_from_sample(int cpu, void *sample)
+{
+	struct aperfmperf_sample *s = sample;
+
+	if (!sample)
+		return 0;
+
+	if (!cpu_khz)
+		return 0;
+
+	if (!boot_cpu_has(X86_FEATURE_APERFMPERF))
+		return 0;
+
+	if (!housekeeping_cpu(cpu, HK_FLAG_MISC))
+		return 0;
+
+	smp_call_function_single(cpu, aperfmperf_snapshot_khz, s, 1);
+
+	return s->khz;
+}
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 02ab56b2a0d8..36e6dbd87317 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -695,6 +695,11 @@ __weak unsigned int arch_freq_get_on_cpu(int cpu)
 	return 0;
 }
 
+__weak unsigned int arch_freq_get_on_cpu_from_sample(int cpu, void *sample)
+{
+	return 0;
+}
+
 static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
 {
 	ssize_t ret;
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 8f141d4c859c..129083684ca0 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -1005,6 +1005,7 @@ static inline void sched_cpufreq_governor_change(struct cpufreq_policy *policy,
 
 extern void arch_freq_prepare_all(void);
 extern unsigned int arch_freq_get_on_cpu(int cpu);
+extern unsigned int arch_freq_get_on_cpu_from_sample(int cpu, void *sample);
 
 extern void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq,
 				unsigned long max_freq);
-- 
2.28.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ