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,  7 Oct 2014 23:26:12 -0700
From:	Mike Turquette <mturquette@...aro.org>
To:	Morten Rasmussen <morten.rasmussen@....com>, peterz@...radead.org,
	mingo@...hat.com
Cc:	dietmar.eggemann@....com, pjt@...gle.com, bsegall@...gle.com,
	vincent.guittot@...aro.org, nicolas.pitre@...aro.org,
	rjw@...ysocki.net, linux-kernel@...r.kernel.org,
	tuukka.tikkanen@...aro.org, Mike Turquette <mturquette@...aro.org>
Subject: [PATCH RFC 2/2] cpufreq: arm_big_little: provide cpu capacity

Move the cpu capacity bits out of arch/arm/ and into the CPUfreq driver.
Not all ARM devices will use CPUfreq and it is unsafe to assume as such
in topology.c.

Instead, use the new capacity_ops introduced into CFS. If this code is
generic enough then it could be factored and shared via a header to make
it easier for other CPUfreq drivers to take advantage of it.

Signed-off-by: Mike Turquette <mturquette@...aro.org>
---
This approach simply builds on top of Morten's series. I am not sure
that the per-cpu method is the best way to go in the future. And if so I
imagine that the CPUfreq core could provide everything except for the
cpu_eff part.

In general I think that the overlap between CPUfreq drivers and
arch/arm/kernel/topology.c is something that needs to addresssed soon,
as both pieces of code are re-inventing parts of each other.

 arch/arm/include/asm/topology.h  |  2 ++
 arch/arm/kernel/topology.c       | 42 ++-------------------------------
 drivers/cpufreq/arm_big_little.c | 51 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 40 deletions(-)

diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h
index 2fe85ff..3951232 100644
--- a/arch/arm/include/asm/topology.h
+++ b/arch/arm/include/asm/topology.h
@@ -14,6 +14,8 @@ struct cputopo_arm {
 };
 
 extern struct cputopo_arm cpu_topology[NR_CPUS];
+extern unsigned long max_raw_capacity;
+DECLARE_PER_CPU(unsigned long, cpu_raw_capacity);
 
 #define topology_physical_package_id(cpu)	(cpu_topology[cpu].socket_id)
 #define topology_core_id(cpu)		(cpu_topology[cpu].core_id)
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index 5f049ec..a2c9b5f 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -79,8 +79,8 @@ static unsigned long *__cpu_capacity;
 
 static unsigned long middle_capacity = 1;
 
-static unsigned long max_raw_capacity = 1;
-static DEFINE_PER_CPU(unsigned long, cpu_raw_capacity);
+unsigned long max_raw_capacity = 1;
+DEFINE_PER_CPU(unsigned long, cpu_raw_capacity);
 
 /*
  * Iterate all CPUs' descriptor in DT and compute the efficiency
@@ -175,44 +175,6 @@ static void update_cpu_capacity(unsigned int cpu)
 		cpu, arch_scale_freq_capacity(NULL, cpu));
 }
 
-/*
- * Scheduler load-tracking scale-invariance
- *
- * Provides the scheduler with a scale-invariance correction factor that
- * compensates for frequency scaling and micro-architecture differences between
- * cpus.
- */
-
-static DEFINE_PER_CPU(atomic_long_t, cpu_curr_freq);
-static DEFINE_PER_CPU(atomic_long_t, cpu_max_freq);
-
-/* cpufreq callback function setting current cpu frequency */
-void arch_scale_set_curr_freq(int cpu, unsigned long freq)
-{
-	atomic_long_set(&per_cpu(cpu_curr_freq, cpu), freq);
-}
-
-/* cpufreq callback function setting max cpu frequency */
-void arch_scale_set_max_freq(int cpu, unsigned long freq)
-{
-	atomic_long_set(&per_cpu(cpu_max_freq, cpu), freq);
-}
-
-unsigned long arch_scale_load_capacity(int cpu)
-{
-	unsigned long curr = atomic_long_read(&per_cpu(cpu_curr_freq, cpu));
-	unsigned long max = atomic_long_read(&per_cpu(cpu_max_freq, cpu));
-	unsigned long ret;
-
-	if (!max || !per_cpu(cpu_raw_capacity, cpu))
-		return SCHED_CAPACITY_SCALE;
-
-	ret = (curr * SCHED_CAPACITY_SCALE) / max;
-	ret = (ret * per_cpu(cpu_raw_capacity, cpu)) / max_raw_capacity;
-
-	return ret;
-}
-
 #else
 static inline void parse_dt_topology(void) {}
 static inline void update_cpu_capacity(unsigned int cpuid) {}
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index a46c223..5baffbd 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -31,7 +31,10 @@
 #include <linux/slab.h>
 #include <linux/topology.h>
 #include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/rcupdate.h>
 #include <asm/bL_switcher.h>
+#include <asm/topology.h>
 
 #include "arm_big_little.h"
 
@@ -533,9 +536,52 @@ static struct notifier_block bL_switcher_notifier = {
 	.notifier_call = bL_cpufreq_switcher_notifier,
 };
 
+/*
+ * Scheduler load-tracking scale-invariance
+ *
+ * Provides the scheduler with a scale-invariance correction factor that
+ * compensates for frequency scaling and micro-architecture differences between
+ * cpus.
+ */
+
+static DEFINE_PER_CPU(atomic_long_t, cpu_curr_freq);
+static DEFINE_PER_CPU(atomic_long_t, cpu_max_freq);
+
+/* cpufreq callback function setting current cpu frequency */
+void arch_scale_set_curr_freq(int cpu, unsigned long freq)
+{
+	atomic_long_set(&per_cpu(cpu_curr_freq, cpu), freq);
+}
+
+/* cpufreq callback function setting max cpu frequency */
+void arch_scale_set_max_freq(int cpu, unsigned long freq)
+{
+	atomic_long_set(&per_cpu(cpu_max_freq, cpu), freq);
+}
+
+/*
+ * scale_load_capacity returns the current capacity for a given cpu, adjusted
+ * for micro-architectural differences and taking into accout cpu frequency
+ */
+unsigned long scale_load_capacity(int cpu)
+{
+	unsigned long curr = atomic_long_read(&per_cpu(cpu_curr_freq, cpu));
+	unsigned long max = atomic_long_read(&per_cpu(cpu_max_freq, cpu));
+	unsigned long ret;
+
+	if (!max || !per_cpu(cpu_raw_capacity, cpu))
+		return SCHED_CAPACITY_SCALE;
+
+	ret = (curr * SCHED_CAPACITY_SCALE) / max;
+	ret = (ret * per_cpu(cpu_raw_capacity, cpu)) / max_raw_capacity;
+
+	return ret;
+}
+
 int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops)
 {
 	int ret, i;
+	unsigned long flags;
 
 	if (arm_bL_ops) {
 		pr_debug("%s: Already registered: %s, exiting\n", __func__,
@@ -550,6 +596,11 @@ int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops)
 
 	arm_bL_ops = ops;
 
+	spin_lock_irqsave(&cfs_capacity_ops.lock, flags);
+	cfs_capacity_ops.get_capacity = scale_load_capacity;
+	spin_unlock_irqrestore(&cfs_capacity_ops.lock, flags);
+	synchronize_rcu();
+
 	ret = bL_switcher_get_enabled();
 	set_switching_enabled(ret);
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ