linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: broonie@kernel.org (Mark Brown)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/4] arm64: topology: Add support for topology DT bindings
Date: Wed,  8 Jan 2014 17:10:11 +0000	[thread overview]
Message-ID: <1389201013-23794-2-git-send-email-broonie@kernel.org> (raw)
In-Reply-To: <1389201013-23794-1-git-send-email-broonie@kernel.org>

From: Mark Brown <broonie@linaro.org>

Add support for parsing the explicit topology bindings to discover the
topology of the system.

Since it is not currently clear how to map multi-level clusters for the
scheduler all leaf clusters are presented to the scheduler at the same
level. This should be enough to provide good support for current systems.

Signed-off-by: Mark Brown <broonie@linaro.org>
---

This doesn't actually ignore CPUs in the root cpu-map, merely warns
about them.  After looking at ignoring them it seemed like a more
sensible thing to just shove them in a separate cluster for now -
giving the scheduler information about only some of the cores seemed
like it was asking for trouble and trying to do anything more active
seems like a lot of work to unsupport broken systems (if you see what
I mean).  I would expect that the end result of putting them in a
cluster is going to be about the same as not providing information
anyway.

It seems like if this isn't enough then either disabling the affected
CPUs entirely or making the warnings louder is the way forwards.

 arch/arm64/kernel/topology.c | 149 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 853544f30a8b..e77c6b0844be 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -17,11 +17,157 @@
 #include <linux/percpu.h>
 #include <linux/node.h>
 #include <linux/nodemask.h>
+#include <linux/of.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 
 #include <asm/topology.h>
 
+#ifdef CONFIG_OF
+static int cluster_id;
+
+static int __init get_cpu_for_node(struct device_node *node)
+{
+	struct device_node *cpu_node;
+	int cpu;
+
+	cpu_node = of_parse_phandle(node, "cpu", 0);
+	if (!cpu_node) {
+		pr_crit("%s: Unable to parse CPU phandle\n", node->full_name);
+		return -1;
+	}
+
+	for_each_possible_cpu(cpu) {
+		if (of_get_cpu_node(cpu, NULL) == cpu_node)
+			return cpu;
+	}
+
+	pr_crit("Unable to find CPU node for %s\n", cpu_node->full_name);
+	return -1;
+}
+
+static void __init parse_core(struct device_node *core, int core_id)
+{
+	char name[10];
+	bool leaf = true;
+	int i, cpu;
+	struct device_node *t;
+
+	i = 0;
+	do {
+		snprintf(name, sizeof(name), "thread%d", i);
+		t = of_get_child_by_name(core, name);
+		if (t) {
+			leaf = false;
+			cpu = get_cpu_for_node(t);
+			if (cpu >= 0) {
+				pr_info("CPU%d: socket %d core %d thread %d\n",
+					cpu, cluster_id, core_id, i);
+				cpu_topology[cpu].socket_id = cluster_id;
+				cpu_topology[cpu].core_id = core_id;
+				cpu_topology[cpu].thread_id = i;
+			} else {
+				pr_err("%s: Can't get CPU for thread\n",
+				       t->full_name);
+			}
+		}
+		i++;
+	} while (t);
+
+	cpu = get_cpu_for_node(core);
+	if (cpu >= 0) {
+		if (!leaf) {
+			pr_err("%s: Core has both threads and CPU\n",
+			       core->full_name);
+			return;
+		}
+
+		pr_info("CPU%d: socket %d core %d\n",
+			cpu, cluster_id, core_id);
+		cpu_topology[cpu].socket_id = cluster_id;
+		cpu_topology[cpu].core_id = core_id;
+	} else if (leaf) {
+		pr_err("%s: Can't get CPU for leaf core\n", core->full_name);
+	}
+}
+
+static void __init parse_cluster(struct device_node *cluster, int depth)
+{
+	char name[10];
+	bool leaf = true;
+	bool has_cores = false;
+	struct device_node *c;
+	int core_id = 0;
+	int i;
+
+	/*
+	 * First check for child clusters; we currently ignore any
+	 * information about the nesting of clusters and present the
+	 * scheduler with a flat list of them.
+	 */
+	i = 0;
+	do {
+		snprintf(name, sizeof(name), "cluster%d", i);
+		c = of_get_child_by_name(cluster, name);
+		if (c) {
+			parse_cluster(c, depth + 1);
+			leaf = false;
+		}
+		i++;
+	} while (c);
+
+	/* Now check for cores */
+	i = 0;
+	do {
+		snprintf(name, sizeof(name), "core%d", i);
+		c = of_get_child_by_name(cluster, name);
+		if (c) {
+			has_cores = true;
+
+			if (depth == 0)
+				pr_err("%s: cpu-map children should be clusters\n",
+				       c->full_name);
+
+			if (leaf)
+				parse_core(c, core_id++);
+			else
+				pr_err("%s: Non-leaf cluster with core %s\n",
+				       cluster->full_name, name);
+		}
+		i++;
+	} while (c);
+
+	if (leaf && !has_cores)
+		pr_warn("%s: empty cluster\n", cluster->full_name);
+
+	if (leaf)
+		cluster_id++;
+}
+
+static void __init parse_dt_topology(void)
+{
+	struct device_node *cn;
+
+	cn = of_find_node_by_path("/cpus");
+	if (!cn) {
+		pr_err("No CPU information found in DT\n");
+		return;
+	}
+
+	/*
+	 * If topology is provided as a cpu-map it is essentially a
+	 * root cluster.
+	 */
+	cn = of_find_node_by_name(cn, "cpu-map");
+	if (!cn)
+		return;
+	parse_cluster(cn, 0);
+}
+
+#else
+static inline void parse_dt_topology(void) {}
+#endif
+
 /*
  * cpu topology table
  */
@@ -88,5 +234,8 @@ void __init init_cpu_topology(void)
 		cpumask_clear(&cpu_topo->core_sibling);
 		cpumask_clear(&cpu_topo->thread_sibling);
 	}
+
+	parse_dt_topology();
+
 	smp_wmb();
 }
-- 
1.8.5.2

  reply	other threads:[~2014-01-08 17:10 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-08 17:10 [PATCH 1/4] arm64: topology: Implement basic CPU topology support Mark Brown
2014-01-08 17:10 ` Mark Brown [this message]
2014-01-08 18:23   ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Lorenzo Pieralisi
2014-01-08 18:32     ` Mark Brown
2014-01-08 17:10 ` [PATCH 3/4] arm64: topology: Tell the scheduler about the relative power of cores Mark Brown
2014-01-08 18:39   ` Lorenzo Pieralisi
2014-01-08 18:45     ` Mark Brown
2014-01-08 17:10 ` [PATCH 4/4] arm64: topology: Provide relative power numbers for cores Mark Brown
2014-01-08 18:30 ` [PATCH 1/4] arm64: topology: Implement basic CPU topology support Lorenzo Pieralisi
2014-01-08 18:40   ` Mark Brown
2014-01-09 12:40     ` Lorenzo Pieralisi
  -- strict thread matches above, loose matches on Subject: below --
2014-04-22 20:21 [PATCH 1/4] arm64: topology: Initialise default topology state immediately Mark Brown
2014-04-22 20:21 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-04-24 14:48   ` Lorenzo Pieralisi
2014-03-21 17:27 [PATCH 1/4] arm64: topology: Initialise default topology state immediately Mark Brown
2014-03-21 17:27 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-03-24 15:36   ` Lorenzo Pieralisi
2014-03-24 15:45     ` Mark Brown
2014-03-24 16:02       ` Lorenzo Pieralisi
2014-03-24 16:27         ` Mark Brown
2014-02-26  0:48 [PATCH 0/4] arm64: Topology Mark Brown
2014-02-26  0:48 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-02-25  4:25 [PATCH 0/4] arm64: topology: CPU topology support Mark Brown
2014-02-25  4:25 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-02-11 22:06 [PATCH 1/4] arm64: topology: Implement basic CPU topology support Mark Brown
2014-02-11 22:06 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-02-10 13:02 [PATCH 1/4] arm64: topology: Implement basic CPU topology support Mark Brown
2014-02-10 13:02 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-01-15 11:38 [PATCH v12 0/4] arm64 topology Mark Brown
2014-01-15 11:38 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-01-12 19:20 [PATCH v11 0/4] ARMv8 cpu topology Mark Brown
2014-01-12 19:20 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-01-14 11:43   ` Lorenzo Pieralisi
2014-01-14 12:36     ` Mark Brown
2014-01-08 19:12 [PATCH 1/4] arm64: topology: Implement basic CPU topology support Mark Brown
2014-01-08 19:12 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2014-01-09 12:50   ` Lorenzo Pieralisi
2014-01-09 13:26     ` Mark Brown
2013-12-19 20:06 [PATCH 0/4] arm64 topology support Mark Brown
2013-12-19 20:06 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2013-12-16 16:49 [PATCH 1/4] arm64: topology: Implement basic CPU topology support Mark Brown
2013-12-16 16:49 ` [PATCH 2/4] arm64: topology: Add support for topology DT bindings Mark Brown
2013-12-17 17:40   ` Lorenzo Pieralisi
2013-12-17 19:19     ` 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=1389201013-23794-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).