Skip to contentSkip to conversation

DT: CPU h/w id parsing clean-ups and cacheinfo id support

PATCH In review Rob Herring 9 participants 29 messages Oct 6, 2021 – Oct 27, 2021

Subsystems (12)
lore
Share & tools
lore

Rob Herring

author maintainer
#0 lore raw

cover DT: CPU h/w id parsing clean-ups and cacheinfo id support

The first 10 patches add a new function, of_get_cpu_hwid(), which parses CPU DT node 'reg' property, and then use it to replace all the open coded versions of parsing CPU node 'reg' properties.

The last 2 patches add support for populating the cacheinfo 'id' on DT platforms. The minimum associated CPU hwid is used for the id. The id is optional, but necessary for resctrl which is being adapted for Arm MPAM.

Tested on arm64. Compile tested on arm, x86 and powerpc.

Rob

Rob Herring (12):
of: Add of_get_cpu_hwid() to read hardware ID from CPU nodes
ARM: Use of_get_cpu_hwid()
ARM: broadcom: Use of_get_cpu_hwid()
arm64: Use of_get_cpu_hwid()
csky: Use of_get_cpu_hwid()
openrisc: Use of_get_cpu_hwid()
powerpc: Use of_get_cpu_hwid()
riscv: Use of_get_cpu_hwid()
sh: Use of_get_cpu_hwid()
x86: dt: Use of_get_cpu_hwid()
cacheinfo: Allow for >32-bit cache 'id'
cacheinfo: Set cache 'id' based on DT data

 arch/arm/kernel/devtree.c       | 22 ++-------------------
 arch/arm/mach-bcm/bcm63xx_pmb.c |  6 +++---
 arch/arm64/kernel/smp.c         | 31 ++----------------------------
 arch/csky/kernel/smp.c          |  6 ++----
 arch/openrisc/kernel/smp.c      |  6 +-----
 arch/powerpc/kernel/smp.c       |  7 +------
 arch/riscv/kernel/cpu.c         |  3 ++-
 arch/sh/boards/of-generic.c     |  5 ++---
 arch/x86/kernel/devicetree.c    |  5 ++---
 drivers/base/cacheinfo.c        | 34 ++++++++++++++++++++++++++++++++-
 drivers/of/base.c               | 22 +++++++++++++++++++++
 include/linux/cacheinfo.h       |  2 +-
 include/linux/of.h              |  1 +
 13 files changed, 74 insertions(+), 76 deletions(-)
Signature · 1 line
2.30.2
author maintainer
#1 lore raw

PATCH 1/12 of: Add of_get_cpu_hwid() to read hardware ID from CPU nodes

There are various open coded implementions parsing the CPU node 'reg' property which contains the CPU's hardware ID. Introduce a new function, of_get_cpu_hwid(), to read the hardware ID.

All the callers should be DT only code, so no need for an empty function.

---
 drivers/of/base.c  | 22 ++++++++++++++++++++++
 include/linux/of.h |  1 +
 2 files changed, 23 insertions(+)
drivers/of/base.c +22 -0
index f720c0d246f2..e587ab44be22 100644
@@ -286,6 +286,28 @@ const void *of_get_property(const struct device_node *np, const char *name,
 }
 EXPORT_SYMBOL(of_get_property);
 
+/**
+ * of_get_cpu_hwid - Get the hardware ID from a CPU device node
+ *
+ * @cpun: CPU number(logical index) for which device node is required
+ * @thread: The local thread number to get the hardware ID for.
+ *
+ * Return: The hardware ID for the CPU node or ~0ULL if not found.
+ */
+u64 of_get_cpu_hwid(struct device_node *cpun, unsigned int thread)
+{
+	const __be32 *cell;
+	int ac, len;
+
+	ac = of_n_addr_cells(cpun);
+	cell = of_get_property(cpun, "reg", &len);
+	if (!cell || !ac || ((sizeof(*cell) * ac * (thread + 1)) > len))
+		return ~0ULL;
+
+	cell += ac * thread;
+	return of_read_number(cell, ac);
+}
+
 /*
  * arch_match_cpu_phys_id - Match the given logical CPU and physical id
  *
include/linux/of.h +1 -0
index 6f1c41f109bb..807f8168dad9 100644
@@ -353,6 +353,7 @@ extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 extern struct device_node *of_get_next_cpu_node(struct device_node *prev);
 extern struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
 						 int index);
+extern u64 of_get_cpu_hwid(struct device_node *cpun, unsigned int thread);
 
 #define for_each_property_of_node(dn, pp) \
 	for (pp = dn->properties; pp != NULL; pp = pp->next)
Signature · 1 line
2.30.2
Reviewed-by on v1 1/12
#2 lore raw

Re: [PATCH 01/12] of: Add of_get_cpu_hwid() to read hardware ID from CPU nodes

Quoted 7 lines · Rob Herring

There are various open coded implementions parsing the CPU node 'reg' property which contains the CPU's hardware ID. Introduce a new function, of_get_cpu_hwid(), to read the hardware ID.

All the callers should be DT only code, so no need for an empty function.

Thanks for doing this. I postponed and forgot about this though I had planned for this when I touched code around this.

--
Regards,
Sudeep

author maintainer
#3 lore raw

PATCH 2/12 ARM: Use of_get_cpu_hwid()

In reply to Rob Herring

Replace the open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

This change drops an error message for missing 'reg' property, but that should not be necessary as the DT tools will ensure 'reg' is present.

---
 arch/arm/kernel/devtree.c | 22 ++--------------------
 1 file changed, 2 insertions(+), 20 deletions(-)
arch/arm/kernel/devtree.c +2 -20
index 28311dd0fee6..02839d8b6202 100644
@@ -84,33 +84,15 @@ void __init arm_dt_init_cpu_maps(void)
 		return;
 
 	for_each_of_cpu_node(cpu) {
-		const __be32 *cell;
-		int prop_bytes;
-		u32 hwid;
+		u32 hwid = of_get_cpu_hwid(cpu, 0);
 
 		pr_debug(" * %pOF...\n", cpu);
-		/*
-		 * A device tree containing CPU nodes with missing "reg"
-		 * properties is considered invalid to build the
-		 * cpu_logical_map.
-		 */
-		cell = of_get_property(cpu, "reg", &prop_bytes);
-		if (!cell || prop_bytes < sizeof(*cell)) {
-			pr_debug(" * %pOF missing reg property\n", cpu);
-			of_node_put(cpu);
-			return;
-		}
 
 		/*
 		 * Bits n:24 must be set to 0 in the DT since the reg property
 		 * defines the MPIDR[23:0].
 		 */
-		do {
-			hwid = be32_to_cpu(*cell++);
-			prop_bytes -= sizeof(*cell);
-		} while (!hwid && prop_bytes > 0);
-
-		if (prop_bytes || (hwid & ~MPIDR_HWID_BITMASK)) {
+		if (hwid & ~MPIDR_HWID_BITMASK) {
 			of_node_put(cpu);
 			return;
 		}
Signature · 1 line
2.30.2
author maintainer
#4 lore raw

PATCH 3/12 ARM: broadcom: Use of_get_cpu_hwid()

In reply to Rob Herring

Replace open coded parsing of CPU nodes 'reg' property with of_get_cpu_hwid().

Cc Florian Fainelli <[email protected]>
Cc Ray Jui <[email protected]>
Cc Scott Branden <[email protected]>
Cc bcm-kernel-feedback-list at broadcom.com
Cc Russell King <[email protected]>
---
 arch/arm/mach-bcm/bcm63xx_pmb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/mach-bcm/bcm63xx_pmb.c +3 -3
index 0e5a05bac3ea..003f1472ab45 100644
@@ -91,10 +91,10 @@ static int bcm63xx_pmb_get_resources(struct device_node *dn,
 	struct of_phandle_args args;
 	int ret;
 
-	ret = of_property_read_u32(dn, "reg", cpu);
-	if (ret) {
+	*cpu = of_get_cpu_hwid(dn, 0);
+	if (*cpu == ~0U) {
 		pr_err("CPU is missing a reg node\n");
-		return ret;
+		return -ENODEV;
 	}
 
 	ret = of_parse_phandle_with_args(dn, "resets", "#reset-cells",
Signature · 1 line
2.30.2
Acked-by on v1 3/12
#5 lore raw

Re: [PATCH 03/12] ARM: broadcom: Use of_get_cpu_hwid()

Quoted 9 lines · Rob Herring

Replace open coded parsing of CPU nodes 'reg' property with of_get_cpu_hwid().

Cc Florian Fainelli <[email protected]>
Cc Ray Jui <[email protected]>
Cc Scott Branden <[email protected]>
Cc bcm-kernel-feedback-list at broadcom.com
Cc Russell King <[email protected]>
Signature · 1 line
Florian
author maintainer
#6 lore raw

PATCH 4/12 arm64: Use of_get_cpu_hwid()

In reply to Rob Herring

Replace the open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

This change drops an error message for missing 'reg' property, but that should not be necessary as the DT tools will ensure 'reg' is present.

Cc Catalin Marinas <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/kernel/smp.c | 31 ++-----------------------------
 1 file changed, 2 insertions(+), 29 deletions(-)
arch/arm64/kernel/smp.c +2 -29
index 6f6ff072acbd..c5cebc406d24 100644
@@ -466,33 +466,6 @@ void __init smp_prepare_boot_cpu(void)
 	kasan_init_hw_tags();
 }
 
-static u64 __init of_get_cpu_mpidr(struct device_node *dn)
-{
-	const __be32 *cell;
-	u64 hwid;
-
-	/*
-	 * A cpu node with missing "reg" property is
-	 * considered invalid to build a cpu_logical_map
-	 * entry.
-	 */
-	cell = of_get_property(dn, "reg", NULL);
-	if (!cell) {
-		pr_err("%pOF: missing reg property\n", dn);
-		return INVALID_HWID;
-	}
-
-	hwid = of_read_number(cell, of_n_addr_cells(dn));
-	/*
-	 * Non affinity bits must be set to 0 in the DT
-	 */
-	if (hwid & ~MPIDR_HWID_BITMASK) {
-		pr_err("%pOF: invalid reg property\n", dn);
-		return INVALID_HWID;
-	}
-	return hwid;
-}
-
 /*
  * Duplicate MPIDRs are a recipe for disaster. Scan all initialized
  * entries and check for duplicates. If any is found just ignore the
@@ -656,9 +629,9 @@ static void __init of_parse_and_init_cpus(void)
 	struct device_node *dn;
 
 	for_each_of_cpu_node(dn) {
-		u64 hwid = of_get_cpu_mpidr(dn);
+		u64 hwid = of_get_cpu_hwid(dn, 0);
 
-		if (hwid == INVALID_HWID)
+		if (hwid & ~MPIDR_HWID_BITMASK)
 			goto next;
 
 		if (is_mpidr_duplicate(cpu_count, hwid)) {
Signature · 1 line
2.30.2
maintainer Acked-by on v1 4/12
#7 lore raw

Re: [PATCH 04/12] arm64: Use of_get_cpu_hwid()

Quoted 6 lines · Rob Herring

Replace the open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

This change drops an error message for missing 'reg' property, but that should not be necessary as the DT tools will ensure 'reg' is present.

Quoted 6 lines
Cc Catalin Marinas <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/kernel/smp.c | 31 ++-----------------------------
 1 file changed, 2 insertions(+), 29 deletions(-)

It's a shame INVALID_HWID can't be removed too, but looks like it's still used in a couple of places.

Will

Reviewed-by on v1 4/12
#8 lore raw

Re: [PATCH 04/12] arm64: Use of_get_cpu_hwid()

In reply to Rob Herring
Quoted 6 lines · Rob Herring

Replace the open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

This change drops an error message for missing 'reg' property, but that should not be necessary as the DT tools will ensure 'reg' is present.

Signature · 2 lines
Regards,
Sudeep
author maintainer
#9 lore raw

PATCH 5/12 csky: Use of_get_cpu_hwid()

In reply to Rob Herring

Replace open coded parsing of CPU nodes 'reg' property with of_get_cpu_hwid().

Cc Guo Ren <[email protected]>
Cc linux-csky at vger.kernel.org
---
 arch/csky/kernel/smp.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
arch/csky/kernel/smp.c +2 -4
index e2993539af8e..6bb38bc2f39b 100644
@@ -180,15 +180,13 @@ void __init setup_smp_ipi(void)
 void __init setup_smp(void)
 {
 	struct device_node *node = NULL;
-	int cpu;
+	unsigned int cpu;
 
 	for_each_of_cpu_node(node) {
 		if (!of_device_is_available(node))
 			continue;
 
-		if (of_property_read_u32(node, "reg", &cpu))
-			continue;
-
+		cpu = of_get_cpu_hwid(node, 0);
 		if (cpu >= NR_CPUS)
 			continue;
 
Signature · 1 line
2.30.2
author maintainer
#10 lore raw

PATCH 6/12 openrisc: Use of_get_cpu_hwid()

In reply to Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Jonas Bonn <[email protected]>
Cc Stefan Kristiansson <[email protected]>
Cc Stafford Horne <[email protected]>
Cc openrisc at lists.librecores.org
---
 arch/openrisc/kernel/smp.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
arch/openrisc/kernel/smp.c +1 -5
index 415e209732a3..7d5a4f303a5a 100644
@@ -65,11 +65,7 @@ void __init smp_init_cpus(void)
 	u32 cpu_id;
 
 	for_each_of_cpu_node(cpu) {
-		if (of_property_read_u32(cpu, "reg", &cpu_id)) {
-			pr_warn("%s missing reg property", cpu->full_name);
-			continue;
-		}
-
+		cpu_id = of_get_cpu_hwid(cpu);
 		if (cpu_id < NR_CPUS)
 			set_cpu_possible(cpu_id, true);
 	}
Signature · 1 line
2.30.2
maintainer Acked-by on v1 6/12
#11 lore raw

Re: [PATCH 06/12] openrisc: Use of_get_cpu_hwid()

Quoted 17 lines · Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Jonas Bonn <[email protected]>
Cc Stefan Kristiansson <[email protected]>
Cc Stafford Horne <[email protected]>
Cc openrisc at lists.librecores.org
---
 arch/openrisc/kernel/smp.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
arch/openrisc/kernel/smp.c +0 -0
index 415e209732a3..7d5a4f303a5a 100644

arch/openrisc/kernel/smp.c void __init smp_init_cpus(void) · line 68

Quoted 9 lines
arch/openrisc/kernel/smp.c +1 -5
@@ -65,11 +65,7 @@ void __init smp_init_cpus(void)
 	u32 cpu_id;
 
 	for_each_of_cpu_node(cpu) {
-		if (of_property_read_u32(cpu, "reg", &cpu_id)) {
-			pr_warn("%s missing reg property", cpu->full_name);
-			continue;
-		}
-
+		cpu_id = of_get_cpu_hwid(cpu);

You have defined of_get_cpu_hwid to return u64, will this create compiler warnings when since we are storing a u64 into a u32?

It seems only if we make with W=3.

I thought we usually warned on this. Oh well, for the openrisc bits.

Quoted 6 lines
arch/openrisc/kernel/smp.c +0 -0
 		if (cpu_id < NR_CPUS)
 			set_cpu_possible(cpu_id, true);
 	}
Signature · 1 line
2.30.2
author maintainer
#12 lore raw

Re: [PATCH 06/12] openrisc: Use of_get_cpu_hwid()

Quoted 21 lines · Stafford Horne
Quoted 19 lines · Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Jonas Bonn <[email protected]>
Cc Stefan Kristiansson <[email protected]>
Cc Stafford Horne <[email protected]>
Cc openrisc at lists.librecores.org
---
 arch/openrisc/kernel/smp.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
arch/openrisc/kernel/smp.c +0 -0
index 415e209732a3..7d5a4f303a5a 100644
@@ -65,11 +65,7 @@ void __init smp_init_cpus(void)
      u32 cpu_id;
 
Quoted 7 lines

arch/openrisc/kernel/smp.c void __init smp_init_cpus(void) · line 68

Quoted 7 lines
arch/openrisc/kernel/smp.c +1 -5
      for_each_of_cpu_node(cpu) {
-             if (of_property_read_u32(cpu, "reg", &cpu_id)) {
-                     pr_warn("%s missing reg property", cpu->full_name);
-                     continue;
-             }
-
+             cpu_id = of_get_cpu_hwid(cpu);

Oops, that should be: of_get_cpu_hwid(cpu, 0);

I thought I double checked all those...

Quoted 2 lines

You have defined of_get_cpu_hwid to return u64, will this create compiler warnings when since we are storing a u64 into a u32?

I'm counting on the caller to know the max size for their platform.

Quoted 4 lines

It seems only if we make with W=3.

I thought we usually warned on this. Oh well, for the openrisc bits.

That's only on ptr truncation I think.

Quoted 8 lines
Quoted 6 lines
arch/openrisc/kernel/smp.c +0 -1
              if (cpu_id < NR_CPUS)
                      set_cpu_possible(cpu_id, true);
      }
--

2.30.2

maintainer
#13 lore raw

Re: [PATCH 06/12] openrisc: Use of_get_cpu_hwid()

Quoted 22 lines · Rob Herring
Quoted 21 lines · Stafford Horne
Quoted 19 lines · Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Jonas Bonn <[email protected]>
Cc Stefan Kristiansson <[email protected]>
Cc Stafford Horne <[email protected]>
Cc openrisc at lists.librecores.org
---
 arch/openrisc/kernel/smp.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
arch/openrisc/kernel/smp.c +0 -0
index 415e209732a3..7d5a4f303a5a 100644
@@ -65,11 +65,7 @@ void __init smp_init_cpus(void)
      u32 cpu_id;
 
Quoted 9 lines
Quoted 7 lines

arch/openrisc/kernel/smp.c void __init smp_init_cpus(void) · line 68

Quoted 7 lines
arch/openrisc/kernel/smp.c +1 -5
      for_each_of_cpu_node(cpu) {
-             if (of_property_read_u32(cpu, "reg", &cpu_id)) {
-                     pr_warn("%s missing reg property", cpu->full_name);
-                     continue;
-             }
-
+             cpu_id = of_get_cpu_hwid(cpu);

Oops, that should be: of_get_cpu_hwid(cpu, 0);

OK. I checked all other patches in the series, it seems OpenRISC was the only one missing that. Sorry I missed it initially.

Quoted 6 lines

I thought I double checked all those...

Quoted 2 lines

You have defined of_get_cpu_hwid to return u64, will this create compiler warnings when since we are storing a u64 into a u32?

I'm counting on the caller to know the max size for their platform.

OK.

Quoted 6 lines
Quoted 4 lines

It seems only if we make with W=3.

I thought we usually warned on this. Oh well, for the openrisc bits.

That's only on ptr truncation I think.

Right, that makes sense.

-Stafford

#14 lore raw

Re: [PATCH 06/12] openrisc: Use of_get_cpu_hwid()

In reply to Stafford Horne
Quoted 4 lines · Stafford Horne

You have defined of_get_cpu_hwid to return u64, will this create compiler warnings when since we are storing a u64 into a u32?

It seems only if we make with W=3.

Yes. This is done by -Wconversion, "Warn for implicit conversions that may alter a value."

Quoted 1 line

I thought we usually warned on this.

This warning is not in -Wall or -Wextra either, it suffers too much from false positives. It is very natural to just ignore the high bits of modulo types (which is what "unsigned" types *are*). Or the bits that "fall off" on a conversion. The C standard makes this required behaviour, it is useful, and it is the only convenient way of getting this!

Segher

maintainer
#15 lore raw

Re: [PATCH 06/12] openrisc: Use of_get_cpu_hwid()

Hi Segher,

Quoted 8 lines · Segher Boessenkool
Quoted 4 lines · Stafford Horne

You have defined of_get_cpu_hwid to return u64, will this create compiler warnings when since we are storing a u64 into a u32?

It seems only if we make with W=3.

Yes. This is done by -Wconversion, "Warn for implicit conversions that may alter a value."

Yeah, that is what I found out when I looked into it.

Quoted 8 lines
Quoted 1 line

I thought we usually warned on this.

This warning is not in -Wall or -Wextra either, it suffers too much from false positives. It is very natural to just ignore the high bits of modulo types (which is what "unsigned" types *are*). Or the bits that "fall off" on a conversion. The C standard makes this required behaviour, it is useful, and it is the only convenient way of getting this!

Thanks for the background, It does make sense. I guess I was confused with java which requires casting when you store to a smaller size. I.e.

Test.java:5: error: incompatible types: possible lossy conversion from int to short
s = i;

-Stafford

#16 lore raw

RE: [PATCH 06/12] openrisc: Use of_get_cpu_hwid()

In reply to Segher Boessenkool

From: Segher Boessenkool

Quoted 12 lines

Sent: 06 October 2021 22:27

Quoted 4 lines · Stafford Horne

You have defined of_get_cpu_hwid to return u64, will this create compiler warnings when since we are storing a u64 into a u32?

It seems only if we make with W=3.

Yes. This is done by -Wconversion, "Warn for implicit conversions that may alter a value."

Quoted 1 line

I thought we usually warned on this.

The microsoft compiler does - best to turn all those warnings off.

Quoted 6 lines

This warning is not in -Wall or -Wextra either, it suffers too much from false positives. It is very natural to just ignore the high bits of modulo types (which is what "unsigned" types *are*). Or the bits that "fall off" on a conversion. The C standard makes this required behaviour, it is useful, and it is the only convenient way of getting this!

I've also seen a compiler convert:

	struct->char_member = (char)(int_val & 0xff);
into:
	reg = int_val;
	reg &= 0xff; // for the & 0xff
	reg &= 0xff; // for the cast
	struct->char_member = low_8bits(reg);

You really don't want the extra noise.

I'll bet that (char)int_val is actually an arithmetic expression. So its type will be 'int'.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)

author maintainer
#17 lore raw

PATCH 7/12 powerpc: Use of_get_cpu_hwid()

In reply to Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Michael Ellerman <[email protected]>
Cc Benjamin Herrenschmidt <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc linuxppc-dev at lists.ozlabs.org
---
 arch/powerpc/kernel/smp.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
arch/powerpc/kernel/smp.c +1 -6
index 9cc7d3dbf439..d96b0e361a73 100644
@@ -1313,18 +1313,13 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 int cpu_to_core_id(int cpu)
 {
 	struct device_node *np;
-	const __be32 *reg;
 	int id = -1;
 
 	np = of_get_cpu_node(cpu, NULL);
 	if (!np)
 		goto out;
 
-	reg = of_get_property(np, "reg", NULL);
-	if (!reg)
-		goto out;
-
-	id = be32_to_cpup(reg);
+	id = of_get_cpu_hwid(np, 0);
 out:
 	of_node_put(np);
 	return id;
Signature · 1 line
2.30.2
reviewer Acked-by on v1 7/12
#18 lore raw

Re: [PATCH 07/12] powerpc: Use of_get_cpu_hwid()

Quoted 26 lines · Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Michael Ellerman <[email protected]>
Cc Benjamin Herrenschmidt <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc linuxppc-dev at lists.ozlabs.org
---
 arch/powerpc/kernel/smp.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
arch/powerpc/kernel/smp.c +0 -1
index 9cc7d3dbf439..d96b0e361a73 100644
@@ -1313,18 +1313,13 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 int cpu_to_core_id(int cpu)
 {
 	struct device_node *np;
-	const __be32 *reg;
 	int id = -1;
 
 	np = of_get_cpu_node(cpu, NULL);
 	if (!np)
 		goto out;

arch/powerpc/kernel/smp.c int __cpu_up(unsigned int cpu, struct task_struct *tidle) · line 1325

Quoted 10 lines
arch/powerpc/kernel/smp.c +1 -5
 
-	reg = of_get_property(np, "reg", NULL);
-	if (!reg)
-		goto out;
-
-	id = be32_to_cpup(reg);
+	id = of_get_cpu_hwid(np, 0);
 out:
 	of_node_put(np);
 	return id;

This looks OK to me.

All the systems I can find have a /cpus/#address-cells of 1, so the change to use of_n_addr_cells() in of_get_cpu_hwid() should be fine.

I booted it on a bunch of systems with no issues.

cheers

author maintainer
#19 lore raw

PATCH 8/12 riscv: Use of_get_cpu_hwid()

In reply to Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Paul Walmsley <[email protected]>
Cc Palmer Dabbelt <[email protected]>
Cc Albert Ou <[email protected]>
Cc linux-riscv at lists.infradead.org
---
 arch/riscv/kernel/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/riscv/kernel/cpu.c +2 -1
index 6d59e6906fdd..f13b2c9ea912 100644
@@ -22,7 +22,8 @@ int riscv_of_processor_hartid(struct device_node *node)
 		return -ENODEV;
 	}
 
-	if (of_property_read_u32(node, "reg", &hart)) {
+	hart = of_get_cpu_hwid(node, 0);
+	if (hart == ~0U) {
 		pr_warn("Found CPU without hart ID\n");
 		return -ENODEV;
 	}
Signature · 1 line
2.30.2
author maintainer
#20 lore raw

PATCH 9/12 sh: Use of_get_cpu_hwid()

In reply to Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Yoshinori Sato <[email protected]>
Cc Rich Felker <[email protected]>
Cc linux-sh at vger.kernel.org
---
 arch/sh/boards/of-generic.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
arch/sh/boards/of-generic.c +2 -3
index 921d76fc3358..f7f3e618e85b 100644
@@ -62,9 +62,8 @@ static void sh_of_smp_probe(void)
 	init_cpu_possible(cpumask_of(0));
 
 	for_each_of_cpu_node(np) {
-		const __be32 *cell = of_get_property(np, "reg", NULL);
-		u64 id = -1;
-		if (cell) id = of_read_number(cell, of_n_addr_cells(np));
+		u64 id = of_get_cpu_hwid(np, 0);
+
 		if (id < NR_CPUS) {
 			if (!method)
 				of_property_read_string(np, "enable-method", &method);
Signature · 1 line
2.30.2
maintainer Acked-by on v1 9/12
#21 lore raw

Re: [PATCH 09/12] sh: Use of_get_cpu_hwid()

Quoted 29 lines · Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Yoshinori Sato <[email protected]>
Cc Rich Felker <[email protected]>
Cc linux-sh at vger.kernel.org
---
 arch/sh/boards/of-generic.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
arch/sh/boards/of-generic.c +2 -3
index 921d76fc3358..f7f3e618e85b 100644
@@ -62,9 +62,8 @@ static void sh_of_smp_probe(void)
 	init_cpu_possible(cpumask_of(0));
 
 	for_each_of_cpu_node(np) {
-		const __be32 *cell = of_get_property(np, "reg", NULL);
-		u64 id = -1;
-		if (cell) id = of_read_number(cell, of_n_addr_cells(np));
+		u64 id = of_get_cpu_hwid(np, 0);
+
 		if (id < NR_CPUS) {
 			if (!method)
 				of_property_read_string(np, "enable-method", &method);
Signature · 1 line
2.30.2
author maintainer
#22 lore raw

PATCH 10/12 x86: dt: Use of_get_cpu_hwid()

In reply to Rob Herring

Replace open coded parsing of CPU nodes' 'reg' property with of_get_cpu_hwid().

Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc x86 at kernel.org
Cc "H. Peter Anvin" <[email protected]>
---
 arch/x86/kernel/devicetree.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
arch/x86/kernel/devicetree.c +2 -3
index 6a4cb71c2498..3aa1e99df2a9 100644
@@ -139,12 +139,11 @@ static void __init dtb_cpu_setup(void)
 {
 	struct device_node *dn;
 	u32 apic_id, version;
-	int ret;
 
 	version = GET_APIC_VERSION(apic_read(APIC_LVR));
 	for_each_of_cpu_node(dn) {
-		ret = of_property_read_u32(dn, "reg", &apic_id);
-		if (ret < 0) {
+		apic_id = of_get_cpu_hwid(dn, 0);
+		if (apic_id == ~0U) {
 			pr_warn("%pOF: missing local APIC ID\n", dn);
 			continue;
 		}
Signature · 1 line
2.30.2
author maintainer
#23 lore raw

PATCH 11/12 cacheinfo: Allow for >32-bit cache 'id'

In reply to Rob Herring

In preparation to set the cache 'id' based on the CPU h/w ids, allow for 64-bit bit 'id' value. The only case that needs this is arm64, so unsigned long is sufficient.

Cc Greg Kroah-Hartman <[email protected]>
Cc "Rafael J. Wysocki" <[email protected]>
---
 drivers/base/cacheinfo.c  | 8 +++++++-
 include/linux/cacheinfo.h | 2 +-
 2 files changed, 8 insertions(+), 2 deletions(-)
drivers/base/cacheinfo.c +7 -1
index dad296229161..66d10bdb863b 100644
@@ -366,13 +366,19 @@ static ssize_t file_name##_show(struct device *dev,		\
 	return sysfs_emit(buf, "%u\n", this_leaf->object);	\
 }
 
-show_one(id, id);
 show_one(level, level);
 show_one(coherency_line_size, coherency_line_size);
 show_one(number_of_sets, number_of_sets);
 show_one(physical_line_partition, physical_line_partition);
 show_one(ways_of_associativity, ways_of_associativity);
 
+static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct cacheinfo *this_leaf = dev_get_drvdata(dev);
+
+	return sysfs_emit(buf, "%lu\n", this_leaf->id);
+}
+
 static ssize_t size_show(struct device *dev,
 			 struct device_attribute *attr, char *buf)
 {
include/linux/cacheinfo.h +1 -1
index 2f909ed084c6..b2e7f3e40204 100644
@@ -48,7 +48,7 @@ extern unsigned int coherency_max_size;
  * keeping, the remaining members form the core properties of the cache
  */
 struct cacheinfo {
-	unsigned int id;
+	unsigned long id;
 	enum cache_type type;
 	unsigned int level;
 	unsigned int coherency_line_size;
Signature · 1 line
2.30.2
Reviewed-by on v1 11/12
#24 lore raw

Re: [PATCH 11/12] cacheinfo: Allow for >32-bit cache 'id'

Quoted 4 lines · Rob Herring

In preparation to set the cache 'id' based on the CPU h/w ids, allow for 64-bit bit 'id' value. The only case that needs this is arm64, so unsigned long is sufficient.

Signature · 2 lines
Regards,
Sudeep
author maintainer
#25 lore raw

PATCH 12/12 cacheinfo: Set cache 'id' based on DT data

In reply to Rob Herring

Use the minimum CPU h/w id of the CPUs associated with the cache for the cache 'id'. This will provide a stable id value for a given system. As we need to check all possible CPUs, we can't use the shared_cpu_map which is just online CPUs. As there's not a cache to CPUs mapping in DT, we have to walk all CPU nodes and then walk cache levels.

Cc Greg Kroah-Hartman <[email protected]>
Cc "Rafael J. Wysocki" <[email protected]>
---
 drivers/base/cacheinfo.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
drivers/base/cacheinfo.c +26 -0
index 66d10bdb863b..44547fd96f72 100644
@@ -136,6 +136,31 @@ static bool cache_node_is_unified(struct cacheinfo *this_leaf,
 	return of_property_read_bool(np, "cache-unified");
 }
 
+static void cache_of_set_id(struct cacheinfo *this_leaf, struct device_node *np)
+{
+	struct device_node *cpu;
+	unsigned long min_id = ~0UL;
+
+	for_each_of_cpu_node(cpu) {
+		struct device_node *cache_node = cpu;
+		u64 id = of_get_cpu_hwid(cache_node, 0);
+
+		while ((cache_node = of_find_next_cache_node(cache_node))) {
+			if ((cache_node == np) && (id < min_id)) {
+				min_id = id;
+				of_node_put(cache_node);
+				break;
+			}
+			of_node_put(cache_node);
+		}
+	}
+
+	if (min_id != ~0UL) {
+		this_leaf->id = min_id;
+		this_leaf->attributes |= CACHE_ID;
+	}
+}
+
 static void cache_of_set_props(struct cacheinfo *this_leaf,
 			       struct device_node *np)
 {
@@ -151,6 +176,7 @@ static void cache_of_set_props(struct cacheinfo *this_leaf,
 	cache_get_line_size(this_leaf, np);
 	cache_nr_sets(this_leaf, np);
 	cache_associativity(this_leaf);
+	cache_of_set_id(this_leaf, np);
 }
 
 static int cache_setup_of_node(unsigned int cpu)
Signature · 1 line
2.30.2
Acked-by on v1 12/12
#26 lore raw

Re: [PATCH 12/12] cacheinfo: Set cache 'id' based on DT data

Quoted 6 lines · Rob Herring

Use the minimum CPU h/w id of the CPUs associated with the cache for the cache 'id'. This will provide a stable id value for a given system. As we need to check all possible CPUs, we can't use the shared_cpu_map which is just online CPUs. As there's not a cache to CPUs mapping in DT, we have to walk all CPU nodes and then walk cache levels.

Signature · 2 lines
Regards,
Sudeep
Tested-by on the v1 series
#27 lore raw
In reply to Rob Herring
Quoted 9 lines · Rob Herring

The first 10 patches add a new function, of_get_cpu_hwid(), which parses CPU DT node 'reg' property, and then use it to replace all the open coded versions of parsing CPU node 'reg' properties.

The last 2 patches add support for populating the cacheinfo 'id' on DT platforms. The minimum associated CPU hwid is used for the id. The id is optional, but necessary for resctrl which is being adapted for Arm MPAM.

Tested on arm64. Compile tested on arm, x86 and powerpc.

On ARM and ARM64:

lscpu -C continues to work on ARM64 as before with cache properties provided in the FDT.

Signature · 1 line
Florian
author maintainer
#28 lore raw
In reply to Rob Herring
Quoted 13 lines · Rob Herring

The first 10 patches add a new function, of_get_cpu_hwid(), which parses CPU DT node 'reg' property, and then use it to replace all the open coded versions of parsing CPU node 'reg' properties.

The last 2 patches add support for populating the cacheinfo 'id' on DT platforms. The minimum associated CPU hwid is used for the id. The id is optional, but necessary for resctrl which is being adapted for Arm MPAM.

Tested on arm64. Compile tested on arm, x86 and powerpc.

Rob

Quoted 13 lines

Rob Herring (12):
of: Add of_get_cpu_hwid() to read hardware ID from CPU nodes
ARM: Use of_get_cpu_hwid()
ARM: broadcom: Use of_get_cpu_hwid()
arm64: Use of_get_cpu_hwid()
csky: Use of_get_cpu_hwid()
openrisc: Use of_get_cpu_hwid()
powerpc: Use of_get_cpu_hwid()
riscv: Use of_get_cpu_hwid()
sh: Use of_get_cpu_hwid()
x86: dt: Use of_get_cpu_hwid()
cacheinfo: Allow for >32-bit cache 'id'
cacheinfo: Set cache 'id' based on DT data

I've fixed up the openrisc error and applied 1-10 to the DT tree.

The cacheinfo part is going to need some more work. I've found I will need the cache affinity (of possible cpus) as well, so I plan to also store the affinity instead of looping thru caches and cpus again.

Rob