mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/7] powerpc/numa: Enable coregroup support for shared LPARs
@ 2026-10-16 11:04 Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 1/7] powerpc/numa: Remove redundant coregroup enablement Srikar Dronamraju
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Srikar Dronamraju @ 2026-10-16 11:04 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Madhavan Srinivasan, chleroy,
	Srikar Dronamraju, Nicholas Piggin, Shrikanth Hegde,
	Peter Zijlstra, linux-kernel

Coregroup topology is currently disabled for shared LPARs even when
coregroup information is available through the associativity hierarchy.

The associativity hierarchy differs between shared and dedicated LPARs.
For dedicated LPARs, a coregroup level is present when the hierarchy
extends beyond primary_domain_index + 1. For shared LPARs, the hierarchy
has one fewer level and coregroup information is available when it
extends beyond primary_domain_index.

The processor sharing mode is not known when NUMA properties are
initially parsed. It is determined later in pSeries_setup_arch().
CPU associativity therefore initially uses the dedicated-LPAR
interpretation. Once shared processor mode is known, reprocess CPU
associativity to detect the coregroup level using the shared-LPAR
hierarchy.

The series also separates coregroup discovery from NUMA enablement.
CPU associativity is processed even with numa=disabled, while NUMA node,
memory and PCI processing remain disabled.

Patches 1-3 prepare the coregroup detection code by removing redundant
coregroup detection, consolidating the VPHN associativity lookup, and
factoring out the coregroup-level check.

Patches 4-6 allow coregroup discovery with NUMA disabled and restructure
CPU associativity processing so that it can be reused after processor
sharing mode is known.

Patch 7 accounts for the shared-LPAR associativity hierarchy and
reprocesses CPU associativity after shared processor mode has been
identified.

Testing
-------

Tested on:
  - Dedicated LPAR
  - Shared LPAR
  - numa=disabled
  - CPU hotplug
  - Memory hotplug

On a shared LPAR, /proc/schedstat did not contain an MC domain before
the series:

  domain0 SMT 00000000,00000000,00000055 ...
  domain1 PKG 000000ff,000000ff,000000ff ...
  domain2 NUMA ffffffff,ffffffff,ffffffff ...

After the series, an MC domain is present between SMT and PKG:

  domain0 SMT 00000000,00000000,00000055 ...
  domain1 MC 00000000,00000000,000000ff ...
  domain2 PKG 000000ff,000000ff,000000ff ...
  domain3 NUMA ffffffff,ffffffff,ffffffff ...


Srikar Dronamraju (7):
  powerpc/numa: Remove redundant coregroup enablement
  powerpc/numa: Consolidate VPHN associativity lookup
  powerpc/numa: Factor out coregroup availability check
  powerpc/numa: Allow coregroup detection when NUMA is disabled
  powerpc/numa: Consolidate associativity lookup in parse_numa_properties
  powerpc/numa: Extract CPU associativity processing into separate function
  powerpc/numa: Enable coregroup support for shared LPARs

 arch/powerpc/include/asm/topology.h    |   2 +
 arch/powerpc/kernel/smp.c              |   4 -
 arch/powerpc/mm/numa.c                 | 176 +++++++++++--------------
 arch/powerpc/platforms/pseries/setup.c |   6 +
 4 files changed, 83 insertions(+), 105 deletions(-)

-- 
2.47.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/7] powerpc/numa: Remove redundant coregroup enablement
  2026-10-16 11:04 [PATCH 0/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
@ 2026-10-16 11:04 ` Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 2/7] powerpc/numa: Consolidate VPHN associativity lookup Srikar Dronamraju
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Srikar Dronamraju @ 2026-10-16 11:04 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Madhavan Srinivasan, chleroy,
	Srikar Dronamraju, Nicholas Piggin, Shrikanth Hegde,
	Peter Zijlstra, linux-kernel

parse_numa_properties() determines whether the coregroup associativity
level is present and sets coregroup_enabled before find_possible_nodes()
is called.

Therefore, there is no need for find_possible_nodes() to determine the
same information again from the length of the associativity domain
property.

Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
---
 arch/powerpc/mm/numa.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index e97b624203ea..09f7e7b2b192 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1124,7 +1124,7 @@ static void __init find_possible_nodes(void)
 {
 	struct device_node *rtas, *root;
 	const __be32 *domains = NULL;
-	int prop_length, max_nodes;
+	int max_nodes;
 	u32 i;
 
 	if (!numa_enabled)
@@ -1145,13 +1145,10 @@ static void __init find_possible_nodes(void)
 	 */
 	root = of_find_node_by_path("/");
 	if (!of_get_property(root, "ibm,migratable-partition", NULL))
-		domains = of_get_property(rtas,
-					  "ibm,current-associativity-domains",
-					  &prop_length);
+		domains = of_get_property(rtas, "ibm,current-associativity-domains", NULL);
 	of_node_put(root);
 	if (!domains) {
-		domains = of_get_property(rtas, "ibm,max-associativity-domains",
-					&prop_length);
+		domains = of_get_property(rtas, "ibm,max-associativity-domains", NULL);
 		if (!domains)
 			goto out;
 	}
@@ -1164,10 +1161,6 @@ static void __init find_possible_nodes(void)
 			node_set(i, node_possible_map);
 	}
 
-	prop_length /= sizeof(int);
-	if (prop_length > primary_domain_index + 2)
-		coregroup_enabled = 1;
-
 out:
 	of_node_put(rtas);
 }
-- 
2.47.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/7] powerpc/numa: Consolidate VPHN associativity lookup
  2026-10-16 11:04 [PATCH 0/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 1/7] powerpc/numa: Remove redundant coregroup enablement Srikar Dronamraju
@ 2026-10-16 11:04 ` Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 3/7] powerpc/numa: Factor out coregroup availability check Srikar Dronamraju
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Srikar Dronamraju @ 2026-10-16 11:04 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Madhavan Srinivasan, chleroy,
	Srikar Dronamraju, Nicholas Piggin, Shrikanth Hegde,
	Peter Zijlstra, linux-kernel

There are two helpers for retrieving the associativity of a virtual
processor using VPHN. The helper used during NUMA initialization also
handles the case where the CPU is not yet mapped to a logical CPU,
while the helper used for topology updates operates on a logical CPU.

Consolidate them by extending the former helper to handle both cases.
If the argument corresponds to a possible CPU, translate it to its
hardware ID; otherwise, treat it as a hardware CPU ID directly.

Rename __vphn_get_associativity() to vphn_get_associativity() and use
it for both NUMA initialization and topology updates. Return the VPHN
hypercall return code instead of converting all failures to -1, and
remove the duplicate implementation.

Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
---
 arch/powerpc/mm/numa.c | 54 ++++--------------------------------------
 1 file changed, 5 insertions(+), 49 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 09f7e7b2b192..df3b51a1beb4 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -641,7 +641,7 @@ int of_drconf_to_nid_single(struct drmem_lmb *lmb)
 
 #ifdef CONFIG_PPC_SPLPAR
 
-static int __vphn_get_associativity(long lcpu, __be32 *associativity)
+static long vphn_get_associativity(unsigned long lcpu, __be32 *associativity)
 {
 	long rc, hwid;
 
@@ -665,7 +665,7 @@ static int __vphn_get_associativity(long lcpu, __be32 *associativity)
 			return 0;
 	}
 
-	return -1;
+	return rc;
 }
 
 static int vphn_get_nid(long lcpu)
@@ -673,7 +673,7 @@ static int vphn_get_nid(long lcpu)
 	__be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
 
 
-	if (!__vphn_get_associativity(lcpu, associativity))
+	if (!vphn_get_associativity(lcpu, associativity))
 		return associativity_to_nid(associativity);
 
 	return NUMA_NO_NODE;
@@ -681,7 +681,7 @@ static int vphn_get_nid(long lcpu)
 }
 #else
 
-static int __vphn_get_associativity(long lcpu, __be32 *associativity)
+static long vphn_get_associativity(unsigned long lcpu, __be32 *associativity)
 {
 	return -1;
 }
@@ -951,7 +951,7 @@ static int __init parse_numa_properties(void)
 
 		memset(vphn_assoc, 0, VPHN_ASSOC_BUFSIZE * sizeof(__be32));
 
-		if (__vphn_get_associativity(i, vphn_assoc) == 0) {
+		if (vphn_get_associativity(i, vphn_assoc) == 0) {
 			nid = associativity_to_nid(vphn_assoc);
 			initialize_form1_numa_distance(vphn_assoc);
 			index = detect_and_enable_coregroup(vphn_assoc, index);
@@ -1384,43 +1384,6 @@ u64 memory_hotplug_max(void)
 #ifdef CONFIG_PPC_SPLPAR
 static int topology_inited;
 
-/*
- * Retrieve the new associativity information for a virtual processor's
- * home node.
- */
-static long vphn_get_associativity(unsigned long cpu,
-					__be32 *associativity)
-{
-	long rc;
-
-	rc = hcall_vphn(get_hard_smp_processor_id(cpu),
-				VPHN_FLAG_VCPU, associativity);
-
-	switch (rc) {
-	case H_SUCCESS:
-		pr_debug("VPHN hcall succeeded. Reset polling...\n");
-		goto out;
-
-	case H_FUNCTION:
-		pr_err_ratelimited("VPHN unsupported. Disabling polling...\n");
-		break;
-	case H_HARDWARE:
-		pr_err_ratelimited("hcall_vphn() experienced a hardware fault "
-			"preventing VPHN. Disabling polling...\n");
-		break;
-	case H_PARAMETER:
-		pr_err_ratelimited("hcall_vphn() was passed an invalid parameter. "
-			"Disabling polling...\n");
-		break;
-	default:
-		pr_err_ratelimited("hcall_vphn() returned %ld. Disabling polling...\n"
-			, rc);
-		break;
-	}
-out:
-	return rc;
-}
-
 void find_and_update_cpu_nid(int cpu)
 {
 	__be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
@@ -1449,13 +1412,6 @@ static int topology_update_init(void)
 	return 0;
 }
 device_initcall(topology_update_init);
-
-#else
-static long vphn_get_associativity(unsigned long cpu,
-					__be32 *associativity)
-{
-	return -1;
-}
 #endif /* CONFIG_PPC_SPLPAR */
 
 int cpu_to_coregroup_id(int cpu)
-- 
2.47.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/7] powerpc/numa: Factor out coregroup availability check
  2026-10-16 11:04 [PATCH 0/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 1/7] powerpc/numa: Remove redundant coregroup enablement Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 2/7] powerpc/numa: Consolidate VPHN associativity lookup Srikar Dronamraju
@ 2026-10-16 11:04 ` Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 4/7] powerpc/numa: Allow coregroup detection when NUMA is disabled Srikar Dronamraju
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Srikar Dronamraju @ 2026-10-16 11:04 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Madhavan Srinivasan, chleroy,
	Srikar Dronamraju, Nicholas Piggin, Shrikanth Hegde,
	Peter Zijlstra, linux-kernel

Coregroup information is present in the associativity hierarchy when
there is an associativity level beyond the primary NUMA domain.

Factor out the check for the presence of the coregroup associativity
level into a helper so that it can be reused when determining
coregroup availability.

No functional change intended.

Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
---
 arch/powerpc/mm/numa.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index df3b51a1beb4..7cb37cb0c5db 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -889,6 +889,16 @@ static int __init numa_setup_drmem_lmb(struct drmem_lmb *lmb,
 	return 0;
 }
 
+/*
+ * Coregroup info is present in associativity property just after
+ * primary_domain_index. In dedicated LPARs, coregroup info is present only
+ * if primary_domain_index is third from the last or earlier.
+ */
+static bool has_coregroup_level(int index)
+{
+	return index > primary_domain_index + 1;
+}
+
 /*
  * If hierarchy extends beyond primary_domain_index + 1, then next
  * level corresponds to coregroup.
@@ -899,8 +909,7 @@ static int detect_and_enable_coregroup(const __be32 *associativity, int index)
 		goto out;
 
 	index = of_read_number(associativity, 1);
-
-	if (index > primary_domain_index + 1) {
+	if (has_coregroup_level(index)) {
 		coregroup_enabled = 1;
 		return index;
 	}
-- 
2.47.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/7] powerpc/numa: Allow coregroup detection when NUMA is disabled
  2026-10-16 11:04 [PATCH 0/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
                   ` (2 preceding siblings ...)
  2026-10-16 11:04 ` [PATCH 3/7] powerpc/numa: Factor out coregroup availability check Srikar Dronamraju
@ 2026-10-16 11:04 ` Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 5/7] powerpc/numa: Consolidate associativity lookup in parse_numa_properties Srikar Dronamraju
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Srikar Dronamraju @ 2026-10-16 11:04 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Madhavan Srinivasan, chleroy,
	Srikar Dronamraju, Nicholas Piggin, Shrikanth Hegde,
	Peter Zijlstra, linux-kernel

parse_numa_properties() currently returns immediately when NUMA is
disabled, which also prevents CPU associativity from being parsed for
coregroup information.

Move the numa_enabled check after CPU associativity processing so that
coregroup topology can still be detected. Keep node onlining conditional
on NUMA being enabled and return before processing memory and PCI NUMA
information when NUMA is disabled.

This allows coregroup topology to be initialized independently of NUMA
node topology.

Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
---
 arch/powerpc/mm/numa.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 7cb37cb0c5db..ffdb07b995a8 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -925,11 +925,6 @@ static int __init parse_numa_properties(void)
 	const __be32 *associativity;
 	unsigned long i;
 
-	if (numa_enabled == 0) {
-		pr_warn("disabled by user\n");
-		return -1;
-	}
-
 	primary_domain_index = find_primary_domain_index();
 
 	if (primary_domain_index < 0) {
@@ -985,10 +980,15 @@ static int __init parse_numa_properties(void)
 		}
 
 		/* node_set_online() is an UB if 'nid' is negative */
-		if (likely(nid >= 0))
+		if (likely(nid >= 0) && numa_enabled)
 			node_set_online(nid);
 	}
 
+	if (numa_enabled == 0) {
+		pr_warn("disabled by user\n");
+		return -1;
+	}
+
 	get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells);
 
 	for_each_node_by_type(memory, "memory") {
-- 
2.47.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 5/7] powerpc/numa: Consolidate associativity lookup in parse_numa_properties
  2026-10-16 11:04 [PATCH 0/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
                   ` (3 preceding siblings ...)
  2026-10-16 11:04 ` [PATCH 4/7] powerpc/numa: Allow coregroup detection when NUMA is disabled Srikar Dronamraju
@ 2026-10-16 11:04 ` Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 6/7] powerpc/numa: Extract CPU associativity processing into separate function Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 7/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
  6 siblings, 0 replies; 8+ messages in thread
From: Srikar Dronamraju @ 2026-10-16 11:04 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Madhavan Srinivasan, chleroy,
	Srikar Dronamraju, Nicholas Piggin, Shrikanth Hegde,
	Peter Zijlstra, linux-kernel

Refactor the CPU associativity lookup logic to reduce code nesting and
improve readability. Previously, the code had separate paths for VPHN
and device tree lookups with duplicated processing logic.

Consolidate the lookup into a unified flow:
1. Try VPHN associativity if firmware supports it
2. Fall back to device tree associativity if VPHN fails or unavailable
3. Process the associativity information once, regardless of source

No functional change is intended. Both VPHN and device tree paths
continue to work as before, with the common associativity processing
performed in one place.

Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
---
 arch/powerpc/mm/numa.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index ffdb07b995a8..c2aefb60ed5a 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -920,6 +920,7 @@ static int detect_and_enable_coregroup(const __be32 *associativity, int index)
 
 static int __init parse_numa_properties(void)
 {
+	bool vphn = firmware_has_feature(FW_FEATURE_VPHN);
 	struct device_node *memory, *pci;
 	int default_nid = 0, index = 0;
 	const __be32 *associativity;
@@ -951,17 +952,16 @@ static int __init parse_numa_properties(void)
 	 */
 	for_each_present_cpu(i) {
 		__be32 vphn_assoc[VPHN_ASSOC_BUFSIZE];
+		struct device_node *cpu = NULL;
 		int nid = NUMA_NO_NODE;
 
-		memset(vphn_assoc, 0, VPHN_ASSOC_BUFSIZE * sizeof(__be32));
-
-		if (vphn_get_associativity(i, vphn_assoc) == 0) {
-			nid = associativity_to_nid(vphn_assoc);
-			initialize_form1_numa_distance(vphn_assoc);
-			index = detect_and_enable_coregroup(vphn_assoc, index);
-		} else {
-			struct device_node *cpu;
-
+		associativity = NULL;
+		if (vphn) {
+			memset(vphn_assoc, 0, VPHN_ASSOC_BUFSIZE * sizeof(__be32));
+			if (vphn_get_associativity(i, vphn_assoc) == 0)
+				associativity = vphn_assoc;
+		}
+		if (!associativity) {
 			/*
 			 * Don't fall back to default_nid yet -- we will plug
 			 * cpus into nodes once the memory scan has discovered
@@ -971,13 +971,14 @@ static int __init parse_numa_properties(void)
 			BUG_ON(!cpu);
 
 			associativity = of_get_associativity(cpu);
-			if (associativity) {
-				nid = associativity_to_nid(associativity);
-				index = detect_and_enable_coregroup(associativity, index);
-				initialize_form1_numa_distance(associativity);
-			}
-			of_node_put(cpu);
 		}
+		if (associativity) {
+			nid = associativity_to_nid(associativity);
+			initialize_form1_numa_distance(associativity);
+			index = detect_and_enable_coregroup(associativity, index);
+		}
+		if (cpu)
+			of_node_put(cpu);
 
 		/* node_set_online() is an UB if 'nid' is negative */
 		if (likely(nid >= 0) && numa_enabled)
-- 
2.47.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 6/7] powerpc/numa: Extract CPU associativity processing into separate function
  2026-10-16 11:04 [PATCH 0/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
                   ` (4 preceding siblings ...)
  2026-10-16 11:04 ` [PATCH 5/7] powerpc/numa: Consolidate associativity lookup in parse_numa_properties Srikar Dronamraju
@ 2026-10-16 11:04 ` Srikar Dronamraju
  2026-10-16 11:04 ` [PATCH 7/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
  6 siblings, 0 replies; 8+ messages in thread
From: Srikar Dronamraju @ 2026-10-16 11:04 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Madhavan Srinivasan, chleroy,
	Srikar Dronamraju, Nicholas Piggin, Shrikanth Hegde,
	Peter Zijlstra, linux-kernel

Move the CPU associativity processing loop from parse_numa_properties()
into a dedicated process_cpu_associativity() function. This improves code
organization by separating concerns:

- parse_numa_properties() handles overall NUMA initialization
- process_cpu_associativity() focuses on CPU associativity processing

This also allows CPU associativity processing to be invoked again after
the processor sharing mode is known.

No functional change in the initialization flow.

Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
---
 arch/powerpc/mm/numa.c | 65 +++++++++++++++++++++++-------------------
 1 file changed, 36 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index c2aefb60ed5a..fde79f34340e 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -918,44 +918,18 @@ static int detect_and_enable_coregroup(const __be32 *associativity, int index)
 	return -1;
 }
 
-static int __init parse_numa_properties(void)
+static void process_cpu_associativity(void)
 {
 	bool vphn = firmware_has_feature(FW_FEATURE_VPHN);
-	struct device_node *memory, *pci;
-	int default_nid = 0, index = 0;
-	const __be32 *associativity;
 	unsigned long i;
+	int index = 0;
 
-	primary_domain_index = find_primary_domain_index();
-
-	if (primary_domain_index < 0) {
-		/*
-		 * if we fail to parse primary_domain_index from device tree
-		 * mark the numa disabled, boot with numa disabled.
-		 */
-		numa_enabled = false;
-		return primary_domain_index;
-	}
-
-	pr_debug("associativity depth for CPU/Memory: %d\n", primary_domain_index);
-
-	/*
-	 * If it is FORM2 initialize the distance table here.
-	 */
-	if (affinity_form == FORM2_AFFINITY)
-		initialize_form2_numa_distance_lookup_table();
-
-	/*
-	 * Even though we connect cpus to numa domains later in SMP
-	 * init, we need to know the node ids now. This is because
-	 * each node to be onlined must have NODE_DATA etc backing it.
-	 */
 	for_each_present_cpu(i) {
+		const __be32 *associativity = NULL;
 		__be32 vphn_assoc[VPHN_ASSOC_BUFSIZE];
 		struct device_node *cpu = NULL;
 		int nid = NUMA_NO_NODE;
 
-		associativity = NULL;
 		if (vphn) {
 			memset(vphn_assoc, 0, VPHN_ASSOC_BUFSIZE * sizeof(__be32));
 			if (vphn_get_associativity(i, vphn_assoc) == 0)
@@ -984,6 +958,39 @@ static int __init parse_numa_properties(void)
 		if (likely(nid >= 0) && numa_enabled)
 			node_set_online(nid);
 	}
+}
+
+static int __init parse_numa_properties(void)
+{
+	struct device_node *memory, *pci;
+	int default_nid = 0;
+	const __be32 *associativity;
+
+	primary_domain_index = find_primary_domain_index();
+
+	if (primary_domain_index < 0) {
+		/*
+		 * if we fail to parse primary_domain_index from device tree
+		 * mark the numa disabled, boot with numa disabled.
+		 */
+		numa_enabled = false;
+		return primary_domain_index;
+	}
+
+	pr_debug("associativity depth for CPU/Memory: %d\n", primary_domain_index);
+
+	/*
+	 * If it is FORM2 initialize the distance table here.
+	 */
+	if (affinity_form == FORM2_AFFINITY)
+		initialize_form2_numa_distance_lookup_table();
+
+	/*
+	 * Even though we connect cpus to numa domains later in SMP
+	 * init, we need to know the node ids now. This is because
+	 * each node to be onlined must have NODE_DATA etc backing it.
+	 */
+	process_cpu_associativity();
 
 	if (numa_enabled == 0) {
 		pr_warn("disabled by user\n");
-- 
2.47.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 7/7] powerpc/numa: Enable coregroup support for shared LPARs
  2026-10-16 11:04 [PATCH 0/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
                   ` (5 preceding siblings ...)
  2026-10-16 11:04 ` [PATCH 6/7] powerpc/numa: Extract CPU associativity processing into separate function Srikar Dronamraju
@ 2026-10-16 11:04 ` Srikar Dronamraju
  6 siblings, 0 replies; 8+ messages in thread
From: Srikar Dronamraju @ 2026-10-16 11:04 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Madhavan Srinivasan, chleroy,
	Srikar Dronamraju, Nicholas Piggin, Shrikanth Hegde,
	Peter Zijlstra, linux-kernel

Coregroup support is currently disabled for shared LPARs even when the
associativity hierarchy contains the information required to identify
the coregroup level.

The associativity hierarchy differs between shared and dedicated LPARs.
For dedicated LPARs, the hierarchy must extend beyond
primary_domain_index + 1 to contain a coregroup level. Shared LPARs have
one fewer level, so a coregroup is available when the hierarchy extends
beyond primary_domain_index.

Remove the unconditional exclusion of shared processors from coregroup
support and use the appropriate hierarchy when detecting a coregroup
level. Read the coregroup ID from the associativity level immediately
following the primary NUMA domain. If no distinct coregroup ID is
available, fall back to the core ID.

The processor sharing mode is not known when NUMA properties are
initially parsed and is determined later in pSeries_setup_arch().
Therefore, initially process CPU associativity using the existing
dedicated-LPAR interpretation and reprocess it after shared processor
mode is known. During the second pass, only reevaluate coregroup
information and avoid repeating NUMA node and distance initialization.

This allows coregroup topology to be enabled on shared LPARs when the
required associativity information is available.

Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
---
 arch/powerpc/include/asm/topology.h    |  2 ++
 arch/powerpc/kernel/smp.c              |  4 ----
 arch/powerpc/mm/numa.c                 | 28 +++++++++++++++++---------
 arch/powerpc/platforms/pseries/setup.c |  6 ++++++
 4 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index 02c3c9ab3ea9..35230011ef84 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -67,6 +67,7 @@ int of_drconf_to_nid_single(struct drmem_lmb *lmb);
 void update_numa_distance(struct device_node *node);
 
 extern void map_cpu_to_node(int cpu, int node);
+void process_cpu_associativity(bool first_pass);
 #ifdef CONFIG_HOTPLUG_CPU
 extern void unmap_cpu_from_node(unsigned long cpu);
 #endif /* CONFIG_HOTPLUG_CPU */
@@ -104,6 +105,7 @@ static inline void update_numa_distance(struct device_node *node) {}
 
 #ifdef CONFIG_SMP
 static inline void map_cpu_to_node(int cpu, int node) {}
+static inline void process_cpu_associativity(bool first_pass) {}
 #ifdef CONFIG_HOTPLUG_CPU
 static inline void unmap_cpu_from_node(unsigned long cpu) {}
 #endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 6a5a5469aaae..0213ef8d855a 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -1052,10 +1052,6 @@ struct cpumask *cpu_coregroup_mask(int cpu)
 
 static bool has_coregroup_support(void)
 {
-	/* Coregroup identification not available on shared systems */
-	if (is_shared_processor())
-		return 0;
-
 	return coregroup_enabled;
 }
 
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index fde79f34340e..2a5d94550dc0 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -890,12 +890,15 @@ static int __init numa_setup_drmem_lmb(struct drmem_lmb *lmb,
 }
 
 /*
- * Coregroup info is present in associativity property just after
- * primary_domain_index. In dedicated LPARs, coregroup info is present only
- * if primary_domain_index is third from the last or earlier.
+ * Coregroup information follows the primary NUMA domain in the
+ * associativity hierarchy. Shared LPARs have one fewer associativity
+ * level than dedicated LPARs.
  */
 static bool has_coregroup_level(int index)
 {
+	if (is_shared_processor())
+		return index > primary_domain_index;
+
 	return index > primary_domain_index + 1;
 }
 
@@ -918,7 +921,7 @@ static int detect_and_enable_coregroup(const __be32 *associativity, int index)
 	return -1;
 }
 
-static void process_cpu_associativity(void)
+void process_cpu_associativity(bool first_pass)
 {
 	bool vphn = firmware_has_feature(FW_FEATURE_VPHN);
 	unsigned long i;
@@ -947,15 +950,17 @@ static void process_cpu_associativity(void)
 			associativity = of_get_associativity(cpu);
 		}
 		if (associativity) {
-			nid = associativity_to_nid(associativity);
-			initialize_form1_numa_distance(associativity);
+			if (first_pass) {
+				nid = associativity_to_nid(associativity);
+				initialize_form1_numa_distance(associativity);
+			}
 			index = detect_and_enable_coregroup(associativity, index);
 		}
 		if (cpu)
 			of_node_put(cpu);
 
 		/* node_set_online() is an UB if 'nid' is negative */
-		if (likely(nid >= 0) && numa_enabled)
+		if (first_pass && likely(nid >= 0) && numa_enabled)
 			node_set_online(nid);
 	}
 }
@@ -990,7 +995,7 @@ static int __init parse_numa_properties(void)
 	 * init, we need to know the node ids now. This is because
 	 * each node to be onlined must have NODE_DATA etc backing it.
 	 */
-	process_cpu_associativity();
+	process_cpu_associativity(true);
 
 	if (numa_enabled == 0) {
 		pr_warn("disabled by user\n");
@@ -1463,12 +1468,15 @@ int cpu_to_coregroup_id(int cpu)
 		goto out;
 
 	index = of_read_number(associativity, 1);
-	if (index > primary_domain_index + 1)
-		coregroup_id = of_read_number(&associativity[index - 1], 1);
+	if (has_coregroup_level(index))
+		coregroup_id = (int)of_read_number(&associativity[primary_domain_index + 1], 1);
 
 out:
 	if (cpunode)
 		of_node_put(cpunode);
 
+	if (coregroup_id == -1)
+		return cpu_to_core_id(cpu);
+
 	return coregroup_id;
 }
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index f29e7547c995..fd8163200b97 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -874,6 +874,12 @@ static void __init pSeries_setup_arch(void)
 
 		if (lppaca_shared_proc()) {
 			static_branch_enable(&shared_processor);
+
+			/*
+			 * Reprocess CPU associativity now that the shared
+			 * LPAR hierarchy can be interpreted correctly.
+			 */
+			process_cpu_associativity(false);
 			pv_spinlocks_init();
 #ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
 			static_key_slow_inc(&paravirt_steal_enabled);
-- 
2.47.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-10-16 11:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-16 11:04 [PATCH 0/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju
2026-10-16 11:04 ` [PATCH 1/7] powerpc/numa: Remove redundant coregroup enablement Srikar Dronamraju
2026-10-16 11:04 ` [PATCH 2/7] powerpc/numa: Consolidate VPHN associativity lookup Srikar Dronamraju
2026-10-16 11:04 ` [PATCH 3/7] powerpc/numa: Factor out coregroup availability check Srikar Dronamraju
2026-10-16 11:04 ` [PATCH 4/7] powerpc/numa: Allow coregroup detection when NUMA is disabled Srikar Dronamraju
2026-10-16 11:04 ` [PATCH 5/7] powerpc/numa: Consolidate associativity lookup in parse_numa_properties Srikar Dronamraju
2026-10-16 11:04 ` [PATCH 6/7] powerpc/numa: Extract CPU associativity processing into separate function Srikar Dronamraju
2026-10-16 11:04 ` [PATCH 7/7] powerpc/numa: Enable coregroup support for shared LPARs Srikar Dronamraju

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®