LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Jeremy Linton <jeremy.linton@arm.com>
To: linux-acpi@vger.kernel.org
Cc: Sudeep.Holla@arm.com, linux-arm-kernel@lists.infradead.org,
	Lorenzo.Pieralisi@arm.com, hanjun.guo@linaro.org,
	rjw@rjwysocki.net, Will.Deacon@arm.com, Catalin.Marinas@arm.com,
	gregkh@linuxfoundation.org, Mark.Rutland@arm.com,
	linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	wangxiongfeng2@huawei.com, vkilari@codeaurora.org,
	ahs3@redhat.com, Dietmar.Eggemann@arm.com,
	Morten.Rasmussen@arm.com, palmer@sifive.com, lenb@kernel.org,
	john.garry@huawei.com, austinwc@codeaurora.org,
	tnowicki@caviumnetworks.com, jhugo@qti.qualcomm.com,
	timur@qti.qualcomm.com, ard.biesheuvel@linaro.org,
	Jeremy Linton <jeremy.linton@arm.com>
Subject: [PATCH v8 09/13] ACPI/PPTT: Add topology parsing code
Date: Wed, 25 Apr 2018 18:31:17 -0500	[thread overview]
Message-ID: <20180425233121.13270-10-jeremy.linton@arm.com> (raw)
In-Reply-To: <20180425233121.13270-1-jeremy.linton@arm.com>

The PPTT can be used to determine the groupings of CPU's at
given levels in the system. Lets add a few routines to the PPTT
parsing code to return a unique id for each unique level in the
processor hierarchy. This can then be matched to build
thread/core/cluster/die/package/etc mappings for each processing
element in the system.

Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
---
 drivers/acpi/pptt.c  | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h |   4 ++
 2 files changed, 164 insertions(+)

diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index cced71ef851a..0fc4b2654665 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -453,6 +453,86 @@ static void cache_setup_acpi_cpu(struct acpi_table_header *table,
 	}
 }
 
+/* Passing level values greater than this will result in search termination */
+#define PPTT_ABORT_PACKAGE 0xFF
+
+/**
+ * acpi_find_processor_package_id() - Locate the processor structure for a cpu
+ *
+ * Given an acpi_pptt_processor node, walk up until we identify the
+ * package that the node is associated with, or we run out of levels
+ * to request or the search is terminated with a flag match
+ * The level parameter also serves to limit possible loops within the tree.
+ *
+ * Return: acpi_pptt_processor* describing the passed core or NULL
+ */
+static struct acpi_pptt_processor *acpi_find_processor_package_id(struct acpi_table_header *table_hdr,
+								  struct acpi_pptt_processor *cpu,
+								  int level, int flag)
+{
+	struct acpi_pptt_processor *prev_node;
+
+	while (cpu && level) {
+		if (cpu->flags & flag)
+			break;
+		pr_debug("level %d\n", level);
+		prev_node = fetch_pptt_node(table_hdr, cpu->parent);
+		if (prev_node == NULL)
+			break;
+		cpu = prev_node;
+		level--;
+	}
+	return cpu;
+}
+
+/**
+ * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
+ *
+ * Get a unique value given a cpu, and a topology level, that can be
+ * matched to determine which cpus share common topological features
+ * at that level.
+ *
+ * Return: Unique value, or -ENOENT if unable to locate cpu
+ */
+static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
+				     unsigned int cpu, int level, int flag)
+{
+	struct acpi_pptt_processor *cpu_node;
+	u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+
+	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
+	if (cpu_node) {
+		cpu_node = acpi_find_processor_package_id(table, cpu_node,
+							  level, flag);
+		/* Only the first level has a guaranteed id */
+		if (level == 0)
+			return cpu_node->acpi_processor_id;
+		return ACPI_PTR_DIFF(cpu_node, table);
+	}
+	pr_warn_once("PPTT table found, but unable to locate core %d (%d)\n",
+		    cpu, acpi_cpu_id);
+	return -ENOENT;
+}
+
+static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
+{
+	struct acpi_table_header *table;
+	acpi_status status;
+	int retval;
+
+	status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
+	if (ACPI_FAILURE(status)) {
+		pr_warn_once("No PPTT table found, cpu topology may be inaccurate\n");
+		return -ENOENT;
+	}
+	retval = topology_get_acpi_cpu_tag(table, cpu, level, flag);
+	pr_debug("Topology Setup ACPI cpu %d, level %d ret = %d\n",
+		 cpu, level, retval);
+	acpi_put_table(table);
+
+	return retval;
+}
+
 /**
  * acpi_find_last_cache_level() - Determines the number of cache levels for a PE
  * @cpu: Kernel logical cpu number
@@ -516,3 +596,83 @@ int cache_setup_acpi(unsigned int cpu)
 
 	return status;
 }
+
+/**
+ * find_acpi_cpu_topology() - Determine a unique topology value for a given cpu
+ * @cpu: Kernel logical cpu number
+ * @level: The topological level for which we would like a unique ID
+ *
+ * Determine a topology unique ID for each thread/core/cluster/mc_grouping
+ * /socket/etc. This ID can then be used to group peers, which will have
+ * matching ids.
+ *
+ * The search terminates when either the requested level is found or
+ * we reach a root node. Levels beyond the termination point will return the
+ * same unique ID. The unique id for level 0 is the acpi processor id. All
+ * other levels beyond this use a generated value to uniquely identify
+ * a topological feature.
+ *
+ * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
+ * Otherwise returns a value which represents a unique topological feature.
+ */
+int find_acpi_cpu_topology(unsigned int cpu, int level)
+{
+	return find_acpi_cpu_topology_tag(cpu, level, 0);
+}
+
+/**
+ * find_acpi_cpu_cache_topology() - Determine a unique cache topology value
+ * @cpu: Kernel logical cpu number
+ * @level: The cache level for which we would like a unique ID
+ *
+ * Determine a unique ID for each unified cache in the system
+ *
+ * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
+ * Otherwise returns a value which represents a unique topological feature.
+ */
+int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
+{
+	struct acpi_table_header *table;
+	struct acpi_pptt_cache *found_cache;
+	acpi_status status;
+	u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+	struct acpi_pptt_processor *cpu_node = NULL;
+	int ret = -1;
+
+	status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
+	if (ACPI_FAILURE(status)) {
+		pr_warn_once("No PPTT table found, topology may be inaccurate\n");
+		return -ENOENT;
+	}
+
+	found_cache = acpi_find_cache_node(table, acpi_cpu_id,
+					   CACHE_TYPE_UNIFIED,
+					   level,
+					   &cpu_node);
+	if (found_cache)
+		ret = ACPI_PTR_DIFF(cpu_node, table);
+
+	acpi_put_table(table);
+
+	return ret;
+}
+
+
+/**
+ * find_acpi_cpu_topology_package() - Determine a unique cpu package value
+ * @cpu: Kernel logical cpu number
+ *
+ * Determine a topology unique package ID for the given cpu.
+ * This ID can then be used to group peers, which will have matching ids.
+ *
+ * The search terminates when either a level is found with the PHYSICAL_PACKAGE
+ * flag set or we reach a root node.
+ *
+ * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
+ * Otherwise returns a value which represents the package for this cpu.
+ */
+int find_acpi_cpu_topology_package(unsigned int cpu)
+{
+	return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE,
+					  ACPI_PPTT_PHYSICAL_PACKAGE);
+}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 15bfb15c2fa5..032e12a2fdc2 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1297,4 +1297,8 @@ static inline int lpit_read_residency_count_address(u64 *address)
 }
 #endif
 
+int find_acpi_cpu_topology(unsigned int cpu, int level);
+int find_acpi_cpu_topology_package(unsigned int cpu);
+int find_acpi_cpu_cache_topology(unsigned int cpu, int level);
+
 #endif	/*_LINUX_ACPI_H*/
-- 
2.13.6

  parent reply	other threads:[~2018-04-25 23:31 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-25 23:31 [PATCH v8 00/13] Support PPTT for ARM64 Jeremy Linton
2018-04-25 23:31 ` [PATCH v8 01/13] drivers: base: cacheinfo: move cache_setup_of_node() Jeremy Linton
2018-04-25 23:31 ` [PATCH v8 02/13] drivers: base: cacheinfo: setup DT cache properties early Jeremy Linton
2018-04-25 23:31 ` [PATCH v8 03/13] cacheinfo: rename of_node to fw_token Jeremy Linton
2018-04-25 23:31 ` [PATCH v8 04/13] arm64/acpi: Create arch specific cpu to acpi id helper Jeremy Linton
2018-04-26 10:27   ` Sudeep Holla
2018-04-26 18:33     ` Jeremy Linton
2018-04-27 13:08       ` Sudeep Holla
2018-04-25 23:31 ` [PATCH v8 05/13] ACPI/PPTT: Add Processor Properties Topology Table parsing Jeremy Linton
2018-04-27 11:02   ` Rafael J. Wysocki
2018-04-27 16:20     ` Jeremy Linton
2018-04-30  7:59       ` Rafael J. Wysocki
2018-04-25 23:31 ` [PATCH v8 06/13] ACPI: Enable PPTT support on ARM64 Jeremy Linton
2018-04-25 23:31 ` [PATCH v8 07/13] drivers: base cacheinfo: Add support for ACPI based firmware tables Jeremy Linton
2018-04-26 11:05   ` Sudeep Holla
2018-04-26 18:57     ` Jeremy Linton
2018-04-27 12:49       ` Sudeep Holla
2018-04-25 23:31 ` [PATCH v8 08/13] arm64: " Jeremy Linton
2018-04-25 23:31 ` Jeremy Linton [this message]
2018-04-25 23:31 ` [PATCH v8 10/13] arm64: topology: rename cluster_id Jeremy Linton
2018-05-01 14:40   ` Sudeep Holla
2018-05-03 15:14   ` Morten Rasmussen
2018-04-25 23:31 ` [PATCH v8 11/13] arm64: topology: enable ACPI/PPTT based CPU topology Jeremy Linton
2018-05-01 14:46   ` Sudeep Holla
2018-05-02  8:24     ` Rafael J. Wysocki
2018-05-02 22:35       ` Jeremy Linton
2018-05-03  8:41         ` Rafael J. Wysocki
2018-05-03 15:15   ` Morten Rasmussen
2018-04-25 23:31 ` [PATCH v8 12/13] ACPI: Add PPTT to injectable table list Jeremy Linton
2018-04-25 23:31 ` [PATCH v8 13/13] arm64: topology: divorce MC scheduling domain from core_siblings Jeremy Linton
2018-05-01 14:33   ` Sudeep Holla
2018-05-02 11:49     ` Morten Rasmussen
2018-05-02 22:32       ` Jeremy Linton
2018-05-03 11:20         ` Morten Rasmussen
2018-05-02 22:34     ` Jeremy Linton
2018-05-03 15:12   ` Morten Rasmussen
2018-04-26  7:57 ` [PATCH v8 00/13] Support PPTT for ARM64 Ard Biesheuvel
2018-05-04  8:10 ` vkilari
2018-05-04 11:44   ` Sudeep Holla
2018-05-04 11:34 ` Xiongfeng Wang
2018-05-09 13:20 ` Tomasz Nowicki

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=20180425233121.13270-10-jeremy.linton@arm.com \
    --to=jeremy.linton@arm.com \
    --cc=Catalin.Marinas@arm.com \
    --cc=Dietmar.Eggemann@arm.com \
    --cc=Lorenzo.Pieralisi@arm.com \
    --cc=Mark.Rutland@arm.com \
    --cc=Morten.Rasmussen@arm.com \
    --cc=Sudeep.Holla@arm.com \
    --cc=Will.Deacon@arm.com \
    --cc=ahs3@redhat.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=austinwc@codeaurora.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hanjun.guo@linaro.org \
    --cc=jhugo@qti.qualcomm.com \
    --cc=john.garry@huawei.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@sifive.com \
    --cc=rjw@rjwysocki.net \
    --cc=timur@qti.qualcomm.com \
    --cc=tnowicki@caviumnetworks.com \
    --cc=vkilari@codeaurora.org \
    --cc=wangxiongfeng2@huawei.com \
    --subject='Re: [PATCH v8 09/13] ACPI/PPTT: Add topology parsing code' \
    /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

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).