- Resolves: RHEL-184808, Dynamically removing cores from an LPAR is not taking care of NUMA topology - Resolves: RHEL-185098, DLPAR Memory remove/add operations fail
118 lines
3.3 KiB
Diff
118 lines
3.3 KiB
Diff
commit 4cf04b9e75db0da2c199fa12003433b3d0427fd0
|
|
Author: Haren Myneni <haren@linux.ibm.com>
|
|
Date: Sat May 16 11:34:21 2026 -0700
|
|
|
|
drmgr: Add NUMA configuration update for CPU remove
|
|
|
|
This patch adds NUMA node config update for CPU removal. Updates
|
|
number of LMBs and CPUs for each node and also calculates total
|
|
number of CPUs from memory less nodes. This node configuration is
|
|
used to identify the node based on the node ratio from which the
|
|
CPU is selected to remove
|
|
|
|
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
|
|
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
|
|
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
|
|
|
|
diff --git a/src/drmgr/common_numa.h b/src/drmgr/common_numa.h
|
|
index 7aea026..edf4349 100644
|
|
--- a/src/drmgr/common_numa.h
|
|
+++ b/src/drmgr/common_numa.h
|
|
@@ -38,6 +38,7 @@ struct ppcnuma_topology {
|
|
unsigned int lmb_count;
|
|
unsigned int cpuless_node_count;
|
|
unsigned int cpuless_lmb_count;
|
|
+ unsigned int memless_cpu_count;
|
|
unsigned int node_count, node_min, node_max;
|
|
struct ppcnuma_node *nodes[MAX_NUMNODES];
|
|
struct ppcnuma_node *ratio;
|
|
diff --git a/src/drmgr/drslot_chrp_cpu.c b/src/drmgr/drslot_chrp_cpu.c
|
|
index 6a21663..e367634 100644
|
|
--- a/src/drmgr/drslot_chrp_cpu.c
|
|
+++ b/src/drmgr/drslot_chrp_cpu.c
|
|
@@ -26,10 +26,14 @@
|
|
#include <sys/types.h>
|
|
#include <dirent.h>
|
|
#include <librtas.h>
|
|
+#include <numa.h>
|
|
#include "dr.h"
|
|
#include "drcpu.h"
|
|
#include "drpci.h"
|
|
#include "ofdt.h"
|
|
+#include "common_numa.h"
|
|
+
|
|
+#define DEFAULT_LMB_SIZE 0x10000000 /* 256MB */
|
|
|
|
struct cpu_operation;
|
|
typedef int (cpu_op_func_t) (void);
|
|
@@ -395,6 +399,43 @@ static int smt_threads_func(struct dr_info *dr_info)
|
|
return rc;
|
|
}
|
|
|
|
+/*
|
|
+ * Per node CPUs are defined as part of build_numa_topology().
|
|
+ * This function calculates number of LMBs per node based on
|
|
+ * node mememory / lmb-size.
|
|
+ * n_cpus and n_lmbs are used to determine node ratio.
|
|
+ */
|
|
+static int cpu_update_numa_config(void)
|
|
+{
|
|
+ struct ppcnuma_node *node;
|
|
+ unsigned long long node_size;
|
|
+ int rc, nid;
|
|
+ uint64_t lmb_sz;
|
|
+
|
|
+ rc = get_dynamic_lmb_size(&lmb_sz);
|
|
+ /*
|
|
+ * Use the default value if lmb-size property is not available.
|
|
+ * For CPU removal, node ratio will be calculated based on
|
|
+ * total n_lmbs per CPU.
|
|
+ */
|
|
+ if (rc)
|
|
+ lmb_sz = DEFAULT_LMB_SIZE;
|
|
+
|
|
+ ppcnuma_foreach_node(&numa, nid, node) {
|
|
+ node_size = numa_node_size(nid, 0);
|
|
+ /*
|
|
+ * Node has memory
|
|
+ * n_lmbs = Total memory / lmb-size
|
|
+ */
|
|
+ if (node_size) {
|
|
+ node->n_lmbs = node_size / lmb_sz;
|
|
+ } else
|
|
+ numa.memless_cpu_count += node->n_cpus;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int valid_cpu_options(void)
|
|
{
|
|
/* default to a quantity of 1 */
|
|
@@ -442,6 +483,15 @@ int drslot_chrp_cpu(void)
|
|
return -1;
|
|
}
|
|
|
|
+ /*
|
|
+ * Maintain NUMA aware hotplug only for remove and with count request.
|
|
+ */
|
|
+ if (usr_drc_count && (usr_action == REMOVE)) {
|
|
+ build_numa_topology();
|
|
+ if (numa_enabled)
|
|
+ cpu_update_numa_config();
|
|
+ }
|
|
+
|
|
/* If a user specifies a drc name, the quantity to add/remove is
|
|
* one. Enforce that here so the loops in add/remove code behave
|
|
* accordingly.
|
|
@@ -473,6 +523,9 @@ int drslot_chrp_cpu(void)
|
|
if (usr_action == ADD || usr_action == REMOVE)
|
|
run_hooks(DRC_TYPE_CPU, usr_action, HOOK_POST, count);
|
|
|
|
+ if ((usr_action == REMOVE) && numa_enabled)
|
|
+ free_numa_topology();
|
|
+
|
|
free_cpu_drc_info(&dr_info);
|
|
return rc;
|
|
}
|