All of lore.kernel.org
 help / color / mirror / Atom feed
From: broonie@kernel.org (Mark Brown)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/4] arm64: topology: Implement basic CPU topology support
Date: Tue, 25 Feb 2014 13:25:42 +0900	[thread overview]
Message-ID: <1393302345-18253-2-git-send-email-broonie@kernel.org> (raw)
In-Reply-To: <1393302345-18253-1-git-send-email-broonie@kernel.org>

From: Mark Brown <broonie@linaro.org>

Add basic CPU topology support to arm64, based on the existing pre-v8
code and some work done by Mark Hambleton.  This patch does not
implement any topology discovery support since that should be based on
information from firmware, it merely implements the scaffolding for
integration of topology support in the architecture.

No locking of the topology data is done since it is only modified during
CPU bringup with external serialisation from the SMP code.

The goal is to separate the architecture hookup for providing topology
information from the DT parsing in order to ease review and avoid
blocking the architecture code (which will be built on by other work)
with the DT code review by providing something simple and basic.

A following patch will implement support for parsing the DT topology
bindings for ARM, similar patches will be needed for ACPI.

Signed-off-by: Mark Brown <broonie@linaro.org>
---
 arch/arm64/Kconfig                |  24 +++++++++
 arch/arm64/include/asm/topology.h |  39 +++++++++++++++
 arch/arm64/kernel/Makefile        |   1 +
 arch/arm64/kernel/smp.c           |  11 ++++
 arch/arm64/kernel/topology.c      | 102 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 177 insertions(+)
 create mode 100644 arch/arm64/include/asm/topology.h
 create mode 100644 arch/arm64/kernel/topology.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 27bbcfc..fea7b47 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -164,6 +164,30 @@ config SMP
 
 	  If you don't know what to do here, say N.
 
+config CPU_TOPOLOGY
+	bool "Support CPU topology definition"
+	depends on SMP
+	default y
+	help
+	  Support CPU topology definition, based on configuration
+	  provided by the firmware.
+
+config SCHED_MC
+	bool "Multi-core scheduler support"
+	depends on CPU_TOPOLOGY
+	help
+	  Multi-core scheduler support improves the CPU scheduler's decision
+	  making when dealing with multi-core CPU chips at a cost of slightly
+	  increased overhead in some places. If unsure say N here.
+
+config SCHED_SMT
+	bool "SMT scheduler support"
+	depends on CPU_TOPOLOGY
+	help
+	  Improves the CPU scheduler's decision making when dealing with
+	  MultiThreading at a cost of slightly increased overhead in some
+	  places. If unsure say N here.
+
 config NR_CPUS
 	int "Maximum number of CPUs (2-32)"
 	range 2 32
diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
new file mode 100644
index 0000000..c8a47e8
--- /dev/null
+++ b/arch/arm64/include/asm/topology.h
@@ -0,0 +1,39 @@
+#ifndef __ASM_TOPOLOGY_H
+#define __ASM_TOPOLOGY_H
+
+#ifdef CONFIG_CPU_TOPOLOGY
+
+#include <linux/cpumask.h>
+
+struct cpu_topology {
+	int thread_id;
+	int core_id;
+	int cluster_id;
+	cpumask_t thread_sibling;
+	cpumask_t core_sibling;
+};
+
+extern struct cpu_topology cpu_topology[NR_CPUS];
+
+#define topology_physical_package_id(cpu)	(cpu_topology[cpu].cluster_id)
+#define topology_core_id(cpu)		(cpu_topology[cpu].core_id)
+#define topology_core_cpumask(cpu)	(&cpu_topology[cpu].core_sibling)
+#define topology_thread_cpumask(cpu)	(&cpu_topology[cpu].thread_sibling)
+
+#define mc_capable()	(cpu_topology[0].cluster_id != -1)
+#define smt_capable()	(cpu_topology[0].thread_id != -1)
+
+void init_cpu_topology(void);
+void store_cpu_topology(unsigned int cpuid);
+const struct cpumask *cpu_coregroup_mask(int cpu);
+
+#else
+
+static inline void init_cpu_topology(void) { }
+static inline void store_cpu_topology(unsigned int cpuid) { }
+
+#endif
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_ARM_TOPOLOGY_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2d4554b..252b621 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -20,6 +20,7 @@ arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
+arm64-obj-$(CONFIG_CPU_TOPOLOGY)	+= topology.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 7cfb92a..9660750 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -114,6 +114,11 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 	return ret;
 }
 
+static void smp_store_cpu_info(unsigned int cpuid)
+{
+	store_cpu_topology(cpuid);
+}
+
 /*
  * This is the secondary CPU boot entry.  We're using this CPUs
  * idle thread stack, but a set of temporary page tables.
@@ -152,6 +157,8 @@ asmlinkage void secondary_start_kernel(void)
 	 */
 	notify_cpu_starting(cpu);
 
+	smp_store_cpu_info(cpu);
+
 	/*
 	 * OK, now it's safe to let the boot CPU continue.  Wait for
 	 * the CPU migration code to notice that the CPU is online
@@ -390,6 +397,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 	int err;
 	unsigned int cpu, ncores = num_possible_cpus();
 
+	init_cpu_topology();
+
+	smp_store_cpu_info(smp_processor_id());
+
 	/*
 	 * are we trying to boot more cores than exist?
 	 */
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
new file mode 100644
index 0000000..c1e44d5
--- /dev/null
+++ b/arch/arm64/kernel/topology.c
@@ -0,0 +1,102 @@
+/*
+ * arch/arm64/kernel/topology.c
+ *
+ * Copyright (C) 2011,2013 Linaro Limited.
+ *
+ * Based on the arm32 version written by Vincent Guittot in turn based on
+ * arch/sh/kernel/topology.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/percpu.h>
+#include <linux/node.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+
+#include <asm/topology.h>
+
+/*
+ * cpu topology table
+ */
+struct cpu_topology cpu_topology[NR_CPUS];
+EXPORT_SYMBOL_GPL(cpu_topology);
+
+const struct cpumask *cpu_coregroup_mask(int cpu)
+{
+	return &cpu_topology[cpu].core_sibling;
+}
+
+static void update_siblings_masks(unsigned int cpuid)
+{
+	struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
+	int cpu;
+
+	/* update core and thread sibling masks */
+	for_each_possible_cpu(cpu) {
+		cpu_topo = &cpu_topology[cpu];
+
+		if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
+			continue;
+
+		cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+		if (cpu != cpuid)
+			cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
+
+		if (cpuid_topo->core_id != cpu_topo->core_id)
+			continue;
+
+		cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
+		if (cpu != cpuid)
+			cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
+	}
+}
+
+void store_cpu_topology(unsigned int cpuid)
+{
+	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
+
+	/* Something should have picked a topology by the time we get here */
+	if (cpuid_topo->core_id == -1)
+		pr_warn("CPU%u: No topology information configured\n", cpuid);
+	else
+		update_siblings_masks(cpuid);
+}
+
+/*
+ * init_cpu_topology is called at boot when only one cpu is running
+ * which prevent simultaneous write access to cpu_topology array
+ */
+void __init init_cpu_topology(void)
+{
+	unsigned int cpu;
+
+	/* init core mask and power*/
+	for_each_possible_cpu(cpu) {
+		struct cpu_topology *cpu_topo = &cpu_topology[cpu];
+
+		cpu_topo->thread_id = -1;
+		cpu_topo->core_id =  -1;
+		cpu_topo->cluster_id = -1;
+		cpumask_clear(&cpu_topo->core_sibling);
+		cpumask_clear(&cpu_topo->thread_sibling);
+	}
+
+	/*
+	 * Assign all remaining CPUs to a cluster so the scheduler
+	 * doesn't get confused.
+	 */
+	for_each_possible_cpu(cpu) {
+		struct cpu_topology *cpu_topo = &cpu_topology[cpu];
+
+		if (cpu_topo->cluster_id == -1) {
+			cpu_topo->cluster_id = INT_MAX;
+			cpu_topo->core_id = cpu;
+		}
+	}
+}
-- 
1.9.0.rc3

  reply	other threads:[~2014-02-25  4:25 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-25  4:25 [PATCH 0/4] arm64: topology: CPU topology support Mark Brown
2014-02-25  4:25 ` Mark Brown [this message]
2014-02-25 16:54   ` [PATCH 1/4] arm64: topology: Implement basic " Lorenzo Pieralisi
2014-02-26  0:50     ` Mark Brown
2014-02-26 12:32       ` Lorenzo Pieralisi
2014-02-26 14:46         ` Mark Brown
2014-02-26 15:48           ` Catalin Marinas
2014-02-26 17:50             ` Lorenzo Pieralisi
2014-02-27  4:30               ` Mark Brown
2014-02-27  4:20             ` Mark Brown
2014-02-25  4:25 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-02-25  4:25 ` [PATCH 3/4] arm64: topology: Tell the scheduler about the relative power of cores Mark Brown
2014-02-25  4:25 ` [PATCH 4/4] arm64: topology: Provide relative power numbers for cores Mark Brown
  -- strict thread matches above, loose matches on Subject: below --
2014-02-26  0:48 [PATCH 0/4] arm64: Topology Mark Brown
2014-02-26  0:48 ` [PATCH 1/4] arm64: topology: Implement basic CPU topology support Mark Brown
2014-02-11 22:06 Mark Brown
2014-02-10 13:02 Mark Brown
2014-02-10 16:22 ` Catalin Marinas
2014-02-10 16:46   ` Mark Brown
2014-02-11  8:15     ` Vincent Guittot
2014-02-11 10:34       ` Will Deacon
2014-02-11 13:18         ` Vincent Guittot
2014-02-11 14:07           ` Catalin Marinas
2014-02-11 14:46             ` Vincent Guittot
2014-02-11 22:04               ` Mark Brown
2014-02-12  8:04             ` Vincent Guittot
2014-02-12 10:27               ` Catalin Marinas
2014-02-12 12:34                 ` Mark Brown
2014-02-21 15:01 ` Lorenzo Pieralisi
2014-02-22  2:06   ` Mark Brown
2014-02-22 12:26     ` Lorenzo Pieralisi
2014-02-23  2:09       ` Mark Brown
2014-01-15 11:38 [PATCH v12 0/4] arm64 topology Mark Brown
2014-01-15 11:38 ` [PATCH 1/4] arm64: topology: Implement basic CPU topology support Mark Brown
2014-01-12 19:20 [PATCH v11 0/4] ARMv8 cpu topology Mark Brown
2014-01-12 19:20 ` [PATCH 1/4] arm64: topology: Implement basic CPU topology support Mark Brown
2014-01-13 16:10   ` Lorenzo Pieralisi
2014-01-13 16:30     ` Mark Brown
2014-01-13 17:44       ` Lorenzo Pieralisi
2014-01-14  8:17         ` Vincent Guittot
2014-01-13 16:44     ` Vincent Guittot
2014-01-13 17:33       ` Lorenzo Pieralisi
2014-01-08 19:12 Mark Brown
2014-01-09 11:48 ` Catalin Marinas
2014-01-08 17:10 Mark Brown
2014-01-08 18:30 ` Lorenzo Pieralisi
2014-01-08 18:40   ` Mark Brown
2014-01-09 12:40     ` Lorenzo Pieralisi
2013-12-19 20:06 [PATCH 0/4] arm64 " Mark Brown
2013-12-19 20:06 ` [PATCH 1/4] arm64: topology: Implement basic CPU " Mark Brown
2013-12-16 16:49 Mark Brown
2013-12-17 17:06 ` Lorenzo Pieralisi
2013-12-17 19:55   ` Mark Brown
2013-12-18 17:39     ` Lorenzo Pieralisi
2013-12-18 18:00       ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1393302345-18253-2-git-send-email-broonie@kernel.org \
    --to=broonie@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.