Compare commits

...

No commits in common. "c8" and "c10s-private-than" have entirely different histories.

35 changed files with 2709 additions and 616 deletions

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

30
.gitignore vendored
View File

@ -1 +1,29 @@
SOURCES/powerpc-utils-1.3.10.tar.gz powerpc-utils-1.2.2.tar.gz
/powerpc-utils-1.2.6.tar.gz
/powerpc-utils-1.2.10.tar.gz
/powerpc-utils-1.2.11.tar.gz
/powerpc-utils-1.2.12.tar.gz
/powerpc-utils-1.2.14.tar.gz
/powerpc-utils-1.2.15.tar.gz
/powerpc-utils-1.2.16.tar.gz
/powerpc-utils-1.2.17.tar.gz
/powerpc-utils-1.2.18.tar.gz
/powerpc-utils-1.2.19.tar.gz
/powerpc-utils-1.2.20.tar.gz
/powerpc-utils-1.2.22.tar.gz
/powerpc-utils-1.2.23.tar.gz
/powerpc-utils-1.2.24.tar.gz
/powerpc-utils-1.2.27.tar.gz
/v1.3.0.tar.gz
/v1.3.1.tar.gz
/v1.3.3.tar.gz
/powerpc-utils-1.3.4.tar.gz
/powerpc-utils-1.3.5.tar.gz
/powerpc-utils-1.3.6.tar.gz
/powerpc-utils-1.3.7.tar.gz
/powerpc-utils-1.3.8.tar.gz
/powerpc-utils-1.3.9.tar.gz
/powerpc-utils-1.3.10.tar.gz
/powerpc-utils-1.3.11.tar.gz
/powerpc-utils-1.3.12.tar.gz
/powerpc-utils-1.3.13.tar.gz

View File

@ -1,11 +0,0 @@
diff -up powerpc-utils-1.3.10/Makefile.am.me powerpc-utils-1.3.10/Makefile.am
--- powerpc-utils-1.3.10/Makefile.am.me 2022-06-03 12:35:01.335312481 +0200
+++ powerpc-utils-1.3.10/Makefile.am 2022-06-03 14:11:58.453820076 +0200
@@ -229,7 +229,6 @@ install-data-hook:
$(INSTALL_DATA) systemd/smtstate.service $(DESTDIR)${systemd_unit_dir}/
$(INSTALL_DATA) systemd/hcn-init.service $(DESTDIR)${systemd_unit_dir}/
$(INSTALL_DATA) var/lib/powerpc-utils/smt.state $(DESTDIR)/var/lib/@PACKAGE@/
- $(INSTALL_SCRIPT) scripts/functions.suse $(DESTDIR)/usr/lib/@PACKAGE@/
$(INSTALL_SCRIPT) scripts/smtstate $(DESTDIR)@sbindir@
sed -i -e 's,$${exec_prefix},@prefix@,g' $(DESTDIR)${systemd_unit_dir}/smt_off.service
sed -i -e 's,$${exec_prefix},@prefix@,g' $(DESTDIR)${systemd_unit_dir}/smtstate.service

View File

@ -1,84 +0,0 @@
commit 73ba26c1240a25e7699449e82cfc09dad10fed80
Author: Sathvika Vasireddy <sv@linux.ibm.com>
Date: Fri Dec 9 15:26:46 2022 +0530
lparstat: Fix negative values seen while running lparstat with -E option
Negative values are seen while running lparstat with -E option.
This is because delta_purr value is less than delta_idle_purr.
Given that these values are read from different sources, a
small variation in the values is possible. So, in such cases,
round down delta_idle_purr to delta_purr.
Without this patch:
=====
System Configuration
type=Dedicated mode=Capped smt=8 lcpu=240 mem=67033290112 kB cpus=0
ent=240.00
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
-0.03 100.02 3.93GHz[111%] 0.01 110.97
0.00 100.00 3.93GHz[111%] 0.01 110.99
-0.04 100.03 3.93GHz[111%] 0.01 110.98
0.06 99.95 3.93GHz[111%] 0.01 110.99
0.02 99.98 3.93GHz[111%] 0.01 110.99
=====
With this patch:
=====
System Configuration
type=Dedicated mode=Capped smt=8 lcpu=240 mem=67033290112 kB cpus=0
ent=240.00
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
0.03 99.96 3.93GHz[111%] 0.01 110.98
0.00 100.00 3.93GHz[111%] 0.01 110.99
0.03 99.97 3.93GHz[111%] 0.01 110.99
0.00 100.00 3.93GHz[111%] 0.01 110.99
0.09 99.90 3.93GHz[111%] 0.01 110.99
=====
Reported-by: Shirisha Ganta <shirisha.ganta1@ibm.com>
Signed-off-by: Sathvika Vasireddy <sv@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/lparstat.c b/src/lparstat.c
index 31a4ee8..eebba1f 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -492,6 +492,15 @@ void get_cpu_util_purr(struct sysentry *unused_se, char *buf)
delta_purr = get_delta_value("purr");
delta_idle_purr = get_delta_value("idle_purr");
+ /*
+ * Given that these values are read from different
+ * sources (purr from lparcfg and idle_purr from sysfs),
+ * a small variation in the values is possible.
+ * In such cases, round down delta_idle_purr to delta_purr.
+ */
+ if (delta_idle_purr > delta_purr)
+ delta_idle_purr = delta_purr;
+
physc = (delta_purr - delta_idle_purr) / delta_tb;
physc *= 100.00;
@@ -507,6 +516,15 @@ void get_cpu_idle_purr(struct sysentry *unused_se, char *buf)
delta_purr = get_delta_value("purr");
delta_idle_purr = get_delta_value("idle_purr");
+ /*
+ * Given that these values are read from different
+ * sources (purr from lparcfg and idle_purr from sysfs),
+ * a small variation in the values is possible.
+ * In such cases, round down delta_idle_purr to delta_purr.
+ */
+ if (delta_idle_purr > delta_purr)
+ delta_idle_purr = delta_purr;
+
physc = (delta_purr - delta_idle_purr) / delta_tb;
idle = (delta_purr / delta_tb) - physc;
idle *= 100.00;

View File

@ -1,46 +0,0 @@
commit dee15756bcb287ccf39a904be07c90107b13844b
Author: Laurent Dufour <ldufour@linux.ibm.com>
Date: Wed May 3 10:50:15 2023 +0200
lparstat: Fix offline threads uninitialized entries
When some threads are offline, lparstat -E is failing like that:
$ ppc64_cpu --info # CPU 20 is offline
Core 0: 0* 1* 2* 3* 4* 5* 6* 7*
Core 1: 8* 9* 10* 11* 12* 13* 14* 15*
Core 2: 16* 17* 18* 19* 20 21* 22* 23*
Core 3: 24* 25* 26* 27* 28* 29* 30* 31*
Core 4: 32* 33* 34* 35* 36* 37* 38* 39*
Core 5: 40* 41* 42* 43* 44* 45* 46* 47*
$ lparstat -E
Failed to read /sys/devices/system/cpu/cpu0/spurr
The message is complaining about CPU0 but the real issue is that in
parse_sysfs_values() the test cpu_sysfs_fds[i].spurr >= 0 is valid even if
the entry has not been initialized (cpu_sysfs_fds is alloc cleared). So
if the number of threads online seen in assign_cpu_sysfs_fds is lower than
threads_in_system, the loop in parse_sysfs_values() will read uninitialized
entry, where .cpu=0.
To prevent that, unset entries in the cpu_sysfs_fds should have the spurr
fd set to -1.
Signed-off-by: Laurent Dufour <ldufour@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/lparstat.c b/src/lparstat.c
index a9e7bce..d2fdb3f 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -163,6 +163,10 @@ static int assign_cpu_sysfs_fds(int threads_in_system)
cpu_idx++;
}
+ /* Mark extra slots for offline threads unset, see parse_sysfs_values */
+ for (; cpu_idx < threads_in_system; cpu_idx++)
+ cpu_sysfs_fds[cpu_idx].spurr = -1;
+
return 0;
error:
fprintf(stderr, "Failed to open %s: %s\n",

View File

@ -1,93 +0,0 @@
commit b2672fa3d462217ccd057a2cd307af2448e78757
Author: Laurent Dufour <ldufour@linux.ibm.com>
Date: Wed May 3 10:50:14 2023 +0200
lparstat: report mixed SMT state
when SMT state is mixed like this one (CPU 4 is offline):
$ ppc64_cpu --info
Core 0: 0* 1* 2* 3* 4 5* 6* 7*
Core 1: 8* 9* 10* 11* 12* 13* 14* 15*
Core 2: 16* 17* 18* 19* 20* 21* 22* 23*
Core 3: 24* 25* 26* 27* 28* 29* 30* 31*
Core 4: 32* 33* 34* 35* 36* 37* 38* 39*
Core 5: 40* 41* 42* 43* 44* 45* 46* 47*
$ ppc64_cpu --smt
SMT=7: 0
SMT=8: 1-5
ppc64_cpu --smt is handling that nicely but lparstat failed reporting the
SMT state:
$ /usr/sbin/lparstat
Failed to get smt state
System Configuration
type=Dedicated mode=Capped smt=Capped lcpu=6 mem=65969728 kB cpus=0 ent=6.00
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
0.02 0.01 0.00 99.97 3.41 56.83 0.02 0.00 4061778 156
Makes lparstat reporting "smt=mixed" in that case.
__do_smt is now returning 0 when the SMT state is mixed instead of -1 which
is also reported when an error is detected.
This doesn't change the call made by ppc64_cpu which is using
print_smt_state=true and so is expecting a returned value equal to 0 or -1.
With that patch applied, lparstat print that in the above case:
$lparstat
System Configuration
type=Dedicated mode=Capped smt=Mixed lcpu=6 mem=65969728 kB cpus=0 ent=6.00
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
0.01 0.01 0.00 99.97 3.43 57.17 0.02 0.00 4105654 156
Signed-off-by: Laurent Dufour <ldufour@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/common/cpu_info_helpers.c b/src/common/cpu_info_helpers.c
index 925f220..c05d96d 100644
--- a/src/common/cpu_info_helpers.c
+++ b/src/common/cpu_info_helpers.c
@@ -245,7 +245,7 @@ int __do_smt(bool numeric, int cpus_in_system, int threads_per_cpu,
if (smt_state == 0)
smt_state = thread + 1;
else if (smt_state > 0)
- smt_state = -1; /* mix of SMT modes */
+ smt_state = 0; /* mix of SMT modes */
}
}
@@ -257,7 +257,7 @@ int __do_smt(bool numeric, int cpus_in_system, int threads_per_cpu,
printf("SMT=1\n");
else
printf("SMT is off\n");
- } else if (smt_state == -1) {
+ } else if (smt_state == 0) {
for (thread = 0; thread < threads_per_cpu; thread++) {
if (CPU_COUNT_S(cpu_state_size,
cpu_states[thread])) {
diff --git a/src/lparstat.c b/src/lparstat.c
index eebba1f..a9e7bce 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -884,13 +884,15 @@ void get_smt_mode(struct sysentry *se, char *buf)
}
smt_state = parse_smt_state();
- if (smt_state < 0) {
+ if (smt_state == -1) {
fprintf(stderr, "Failed to get smt state\n");
return;
}
if (smt_state == 1)
sprintf(buf, "Off");
+ else if (smt_state == 0)
+ sprintf(buf, "Mixed");
else
sprintf(buf, "%d", smt_state);
}

View File

@ -1,98 +0,0 @@
commit b1b9e76de0f3ab1dfcd9426779fa20fd77cd5625
Author: Luciano Chavez <lnx1138@linux.ibm.com>
Date: Wed Aug 24 21:11:32 2022 -0500
lsslot: Fix lsslot -c mem output when using 4GB LMB size
When using a LMB size of 4GB, the output of lsslot -c mem would get
reported incorrectly as:
Dynamic Reconfiguration Memory (LMB size 0x0)
:
DRC Index: 80000001 Address: 100000000
Removable: No Associativity: (index: 1) 0 1 4 9
Section(s):
This patch changes the declaration of the _node_u._smem._lmb_size from
a uint32_t to uint64_t to store the value properly. Any variables that
store the lmb_size are also declared as uint64_t. In addition, we
use the PRIx64 macro in printf statements to properly print the
lmb_size value.
The patch also includes a necessary change to declare the global
variable block_sz_bytes as a uint64_t to fix an infinite loop in
the function get_mem_scns() when the above changes were introduced.
Signed-off-by: Luciano Chavez <lnx1138@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/drmem.h b/src/drmgr/drmem.h
index db5a47f..48108c5 100644
--- a/src/drmgr/drmem.h
+++ b/src/drmgr/drmem.h
@@ -58,7 +58,7 @@ struct drconf_mem_v2 {
#define LMB_REVERSE_SORT 1
#define LMB_RANDOM_SORT 2
-extern int block_sz_bytes;
+extern uint64_t block_sz_bytes;
struct lmb_list_head *get_lmbs(unsigned int);
void free_lmbs(struct lmb_list_head *);
diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c
index 3b78723..d37ee80 100644
--- a/src/drmgr/drslot_chrp_mem.c
+++ b/src/drmgr/drslot_chrp_mem.c
@@ -33,7 +33,7 @@
#include "drmem.h"
#include "common_numa.h"
-int block_sz_bytes = 0;
+uint64_t block_sz_bytes = 0;
static char *state_strs[] = {"offline", "online"};
static char *usagestr = "-c mem {-a | -r} {-q <quantity> -p {variable_weight | ent_capacity} | {-q <quantity> | -s [<drc_name> | <drc_index>]}}";
@@ -118,7 +118,7 @@ free_lmbs(struct lmb_list_head *lmb_list)
static int
get_mem_scns(struct dr_node *lmb)
{
- uint32_t lmb_sz = lmb->lmb_size;
+ uint64_t lmb_sz = lmb->lmb_size;
uint64_t phys_addr = lmb->lmb_address;
uint32_t mem_scn;
int rc = 0;
diff --git a/src/drmgr/lsslot.c b/src/drmgr/lsslot.c
index 87f876e..83e9e85 100644
--- a/src/drmgr/lsslot.c
+++ b/src/drmgr/lsslot.c
@@ -741,7 +741,7 @@ int print_drconf_mem(struct lmb_list_head *lmb_list)
if (usr_drc_name)
drc_index = strtol(usr_drc_name, NULL, 0);
- printf("Dynamic Reconfiguration Memory (LMB size 0x%x)\n",
+ printf("Dynamic Reconfiguration Memory (LMB size 0x%"PRIx64")\n",
lmb_list->lmbs->lmb_size);
for (lmb = lmb_list->lmbs; lmb; lmb = lmb->next) {
@@ -808,7 +808,7 @@ int lsslot_chrp_mem(void)
if (lmb_list->drconf_buf) {
print_drconf_mem(lmb_list);
} else {
- printf("lmb size: 0x%x\n", lmb_list->lmbs->lmb_size);
+ printf("lmb size: 0x%"PRIx64"\n", lmb_list->lmbs->lmb_size);
printf("%-20s %-5s %c %s\n", "Memory Node", "Name", 'R',
"Sections");
printf("%-20s %-5s %c %s\n", "-----------", "----", '-',
diff --git a/src/drmgr/ofdt.h b/src/drmgr/ofdt.h
index 26c943a..bd90810 100644
--- a/src/drmgr/ofdt.h
+++ b/src/drmgr/ofdt.h
@@ -94,7 +94,7 @@ struct dr_node {
union {
struct mem_info {
uint64_t _address;
- uint32_t _lmb_size;
+ uint64_t _lmb_size;
uint32_t _lmb_aa_index;
struct mem_scn *_mem_scns;
struct of_node *_of_node;

View File

@ -1,29 +0,0 @@
commit e1f1deb06d9168a95a381a2236e1d8c693d3d229
Author: Luciano Chavez <lnx1138@linux.ibm.com>
Date: Wed Aug 24 21:17:54 2022 -0500
lsslot: Explicity declare that lmb_address be displayed in hexadecimal
A printf statement used is lsslot.c was specifying the macro PRIu64 to
display the lmb_address. Depending on the compilation, this would
either display as a hexadecimal or decimal value.
This patch replaces PRIu64 with PRIx64 to explicitly declare to print
the value as hexadecimal as that was is normally expected of an address.
Signed-off-by: Luciano Chavez <lnx1138@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/lsslot.c b/src/drmgr/lsslot.c
index 7ea0f8b..87f876e 100644
--- a/src/drmgr/lsslot.c
+++ b/src/drmgr/lsslot.c
@@ -756,7 +756,7 @@ int print_drconf_mem(struct lmb_list_head *lmb_list)
printf("%s: %s\n", lmb->drc_name,
lmb->is_owned ? "" : "Not Owned");
- printf(" DRC Index: %x Address: %"PRIu64"\n",
+ printf(" DRC Index: %x Address: %"PRIx64"\n",
lmb->drc_index, lmb->lmb_address);
printf(" Removable: %s Associativity: ",
lmb->is_removable ? "Yes" : "No ");

View File

@ -1,93 +0,0 @@
commit f4c2b0d142f623e7dd28a5d685e446d41be75601
Author: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Date: Thu Aug 25 12:19:27 2022 +0530
lparstat: Fix display of mode for dedicated-donating partition
From the lparstat man page:
mode
Indicates whether the partition processor capacity is capped or uncapped
allowing it to consume idle cycles from the shared pool. Dedicated LPAR
is capped or donating.
However, on a dedicated partition, lparstat always displays the mode as
'Capped' today. Fix this by using 'DedDonMode' field from lparcfg for
determining the cycle donation status of a dedicated partition.
On a dedicated-donating partition:
$ grep -e shared -e DedDonMode -e capped /proc/powerpc/lparcfg
DedDonMode=1
capped=1
shared_processor_mode=0
Before this patch:
$ lparstat
System Configuration
type=Dedicated mode=Capped smt=8 lcpu=1 mem=3335424 kB cpus=0 ent=1.00
After this patch:
$ lparstat
System Configuration
type=Dedicated mode=Donating smt=8 lcpu=1 mem=3335424 kB cpus=0 ent=1.00
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Reviewed-by: Nathan Lynch <nathanl@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/lparstat.c b/src/lparstat.c
index 0b30fc9..e998e8c 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -718,6 +718,16 @@ void get_capped_mode(struct sysentry *se, char *buf)
sprintf(buf, "%s", value);
}
+void get_dedicated_mode(struct sysentry *se, char *buf)
+{
+ const char *value = "Capped";
+
+ if (se->value[0] == '1')
+ value = "Donating";
+
+ sprintf(buf, "%s", value);
+}
+
void get_percent_entry(struct sysentry *se, char *buf)
{
float value;
@@ -1057,7 +1067,10 @@ void print_system_configuration(void)
get_sysdata("shared_processor_mode", &descr, value);
offset = sprintf(buf, "type=%s ", value);
sprintf(type, "%s", value);
- get_sysdata("capped", &descr, value);
+ if (!strcmp(value, "Dedicated"))
+ get_sysdata("DedDonMode", &descr, value);
+ else
+ get_sysdata("capped", &descr, value);
offset += sprintf(buf + offset, "mode=%s ", value);
get_sysdata("smt_state", &descr, value);
offset += sprintf(buf + offset, "smt=%s ", value);
diff --git a/src/lparstat.h b/src/lparstat.h
index 26ed4ba..b7c88e9 100644
--- a/src/lparstat.h
+++ b/src/lparstat.h
@@ -47,6 +47,7 @@ typedef struct cpu_sysfs_file_desc cpu_sysfs_fd;
extern void get_smt_state(struct sysentry *, char *);
extern void get_capped_mode(struct sysentry *, char *);
+extern void get_dedicated_mode(struct sysentry *, char *);
extern void get_memory_mode(struct sysentry *, char *);
extern void get_percent_entry(struct sysentry *, char *);
extern void get_phys_cpu_percentage(struct sysentry *, char *);
@@ -110,7 +111,8 @@ struct sysentry system_data[] = {
{.name = "DesVarCapWt",
.descr = "Desired Variable Capacity Weight"},
{.name = "DedDonMode",
- .descr = "Dedicated Donation Mode"},
+ .descr = "Dedicated Donation Mode",
+ .get = &get_dedicated_mode},
{.name = "partition_entitled_capacity",
.descr = "Partition Entitled Capacity"},
{.name = "system_active_processors",

View File

@ -1,27 +0,0 @@
commit acaf9c45a340f9bb49d6b21ba7ad60c21326ea73
Author: Mingming Cao <mmc@linux.vnet.ibm.com>
Date: Mon Nov 7 14:39:02 2022 -0800
hcnmgr: Fix setting primary slave across reboots
Using nmcli to set bonding of primary slave so that is set correctly
across reboots.
Signed-off-by: Mingming Cao <mmc@linux.vnet.ibm.com>
[tyreld: Reworded commit log]
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/scripts/hcnmgr b/scripts/hcnmgr
index 6946ff9..b5a6bfb 100644
--- a/scripts/hcnmgr
+++ b/scripts/hcnmgr
@@ -375,7 +375,8 @@ do_config_vdevice_nm() {
# if the device is primary, and link is up, force it as primary se
if [[ $MODE == "primary" ]]; then
hcnlog INFO "Change bonding primary slave to $DEVNAME"
- echo "$DEVNAME" >"$BOND_PATH"/primary
+ nmcli con mod id "$BONDNAME" +bond.options "primary=$DEVNAME"
+ nmcli con up "$BONDNAME"
fi
hcnlog DEBUG "do_config_vdevice: exit"

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

16
plans/tier1.fmf Normal file
View File

@ -0,0 +1,16 @@
---
summary: Tier1 plan for librtas
discover:
how: fmf
url: https://pkgs.devel.redhat.com/git/tests/librtas
ref: master
filter: tier:1
execute:
how: tmt
adjust:
enabled: false
when: distro == centos-stream or distro == fedora

View File

@ -327,13 +327,13 @@ diff -up powerpc-utils-1.3.5/man/update_flash_nv.8.me powerpc-utils-1.3.5/man/up
+.SH SEE ALSO +.SH SEE ALSO
+update_flash(8). +update_flash(8).
+ +
diff -up powerpc-utils-1.3.10/Makefile.am.me powerpc-utils-1.3.10/Makefile.am diff -up powerpc-utils-1.3.11/Makefile.am.orig powerpc-utils-1.3.11/Makefile.am
--- powerpc-utils-1.3.10/Makefile.am.me 2022-06-03 12:35:01.335312481 +0200 --- powerpc-utils-1.3.11/Makefile.am.orig 2023-01-24 22:20:20.885655802 +0100
+++ powerpc-utils-1.3.10/Makefile.am 2022-06-03 12:46:42.460763120 +0200 +++ powerpc-utils-1.3.11/Makefile.am 2023-01-24 22:22:36.291802414 +0100
@@ -48,7 +48,17 @@ man_MANS = \ @@ -49,7 +49,18 @@ man_MANS = \
man/vcpustat.8 \
man/rtas_dbg.8 \ man/rtas_dbg.8 \
man/drmgr.8 \ man/drmgr.8 \
man/drmgr-hooks.8 \
- man/lparnumascore.8 - man/lparnumascore.8
+ man/lparnumascore.8 \ + man/lparnumascore.8 \
+ man/lsdevinfo.8 \ + man/lsdevinfo.8 \
@ -346,6 +346,7 @@ diff -up powerpc-utils-1.3.10/Makefile.am.me powerpc-utils-1.3.10/Makefile.am
+ man/pseries_platform.8 \ + man/pseries_platform.8 \
+ man/update_flash_nv.8 \ + man/update_flash_nv.8 \
+ man/hcnmgr.8 + man/hcnmgr.8
+
EXTRA_DIST += $(bin_SCRIPTS) $(sbin_SCRIPTS) $(man_MANS) EXTRA_DIST += $(bin_SCRIPTS) $(sbin_SCRIPTS) $(man_MANS)

View File

@ -0,0 +1,163 @@
commit 54cf30c7d274c8aab2a7ae589ab056f52dfffc62
Author: Aboorva Devarajan <aboorvad@linux.ibm.com>
Date: Sat Dec 7 21:54:44 2024 -0500
cpu_info_helpers: Add helper function to retrieve present CPU core list
Introduce get_present_core_list helper function to accurately parse
and retrieve the list of present CPU cores, addressing gaps in core
numbering caused by dynamic addition or removal of CPUs (via CPU DLPAR
operation)
Utilizes the present CPU list from `sys/devices/system/cpu/present`
to handle non-contiguous CPU IDs. Accurately maps core IDs to CPUs
considering specified number of threads per CPU, addressing gaps in
core numbering.
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
diff --git a/src/common/cpu_info_helpers.c b/src/common/cpu_info_helpers.c
index 8c57db8..756e792 100644
--- a/src/common/cpu_info_helpers.c
+++ b/src/common/cpu_info_helpers.c
@@ -203,6 +203,113 @@ int __get_one_smt_state(int core, int threads_per_cpu)
return smt_state;
}
+int get_present_cpu_count(void)
+{
+ int start, end, total_cpus = 0;
+ size_t len = 0;
+ char *line = NULL;
+ FILE *fp;
+ char *token;
+
+ fp = fopen(CPU_PRESENT_PATH, "r");
+ if (!fp) {
+ perror("Error opening CPU_PRESENT_PATH");
+ return -1;
+ }
+
+ if (getline(&line, &len, fp) == -1) {
+ perror("Error reading CPU_PRESENT_PATH");
+ fclose(fp);
+ free(line);
+ return -1;
+ }
+ fclose(fp);
+
+ token = strtok(line, ",");
+ while (token) {
+ if (sscanf(token, "%d-%d", &start, &end) == 2) {
+ total_cpus += (end - start + 1);
+ } else if (sscanf(token, "%d", &start) == 1) {
+ total_cpus++;
+ }
+ token = strtok(NULL, ",");
+ }
+
+ free(line);
+ return total_cpus;
+}
+
+int get_present_core_list(int **present_cores, int *num_present_cores, int threads_per_cpu)
+{
+ FILE *fp = NULL;
+ char *line = NULL;
+ char *token = NULL;
+ size_t len = 0;
+ ssize_t read;
+ int core_count = 0;
+ int core_list_size;
+ int *cores = NULL;
+ int start, end, i;
+
+ if (threads_per_cpu <= 0) {
+ fprintf(stderr, "Invalid threads_per_cpu value, got %d expected >= 1\n", threads_per_cpu);
+ return -1;
+ }
+
+ core_list_size = get_present_cpu_count() / threads_per_cpu;
+ if (core_list_size <= 0) {
+ fprintf(stderr, "Error while calculating core list size\n");
+ return -1;
+ }
+
+ cores = malloc(core_list_size * sizeof(int));
+ if (!cores) {
+ perror("Memory allocation failed");
+ goto cleanup;
+ }
+
+ fp = fopen(CPU_PRESENT_PATH, "r");
+ if (!fp) {
+ perror("Error opening file");
+ goto cleanup;
+ }
+
+ read = getline(&line, &len, fp);
+ if (read == -1) {
+ perror("Error reading file");
+ goto cleanup;
+ }
+
+ token = strtok(line, ",");
+ while (token) {
+ if (sscanf(token, "%d-%d", &start, &end) == 2) {
+ for (i = start; i <= end; i++) {
+ if (i % threads_per_cpu == 0) {
+ cores[core_count++] = i / threads_per_cpu;
+ }
+ }
+ } else if (sscanf(token, "%d", &start) == 1) {
+ if (start % threads_per_cpu == 0) {
+ cores[core_count++] = start / threads_per_cpu;
+ }
+ }
+ token = strtok(NULL, ",");
+ }
+
+ *present_cores = cores;
+ *num_present_cores = core_count;
+ free(line);
+ return 0;
+
+cleanup:
+ if (fp) {
+ fclose(fp);
+ }
+ free(line);
+ free(cores);
+ return -1;
+}
+
static void print_cpu_list(const cpu_set_t *cpuset, int cpuset_size,
int cpus_in_system)
{
diff --git a/src/common/cpu_info_helpers.h b/src/common/cpu_info_helpers.h
index c063fff..77e6ad7 100644
--- a/src/common/cpu_info_helpers.h
+++ b/src/common/cpu_info_helpers.h
@@ -24,9 +24,10 @@
#ifndef _CPU_INFO_HELPERS_H
#define _CPU_INFO_HELPERS_H
-#define SYSFS_CPUDIR "/sys/devices/system/cpu/cpu%d"
-#define SYSFS_SUBCORES "/sys/devices/system/cpu/subcores_per_core"
-#define INTSERV_PATH "/proc/device-tree/cpus/%s/ibm,ppc-interrupt-server#s"
+#define SYSFS_CPUDIR "/sys/devices/system/cpu/cpu%d"
+#define SYSFS_SUBCORES "/sys/devices/system/cpu/subcores_per_core"
+#define INTSERV_PATH "/proc/device-tree/cpus/%s/ibm,ppc-interrupt-server#s"
+#define CPU_PRESENT_PATH "/sys/devices/system/cpu/present"
#define SYSFS_PATH_MAX 128
@@ -39,6 +40,8 @@ extern int num_subcores(void);
extern int get_attribute(char *path, const char *fmt, int *value);
extern int get_cpu_info(int *threads_per_cpu, int *cpus_in_system,
int *threads_in_system);
+extern int get_present_core_list(int **present_cores, int *num_present_cores,
+ int threads_per_cpu);
extern int __is_smt_capable(int threads_in_system);
extern int __get_one_smt_state(int core, int threads_per_cpu);
extern int __do_smt(bool numeric, int cpus_in_system, int threads_per_cpu,

View File

@ -0,0 +1,31 @@
commit 3a8127ad7fe6615a8c6e8a3f0965addfdf888b38
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Feb 14 21:43:33 2025 -0800
drmgr/pci: Return 0 for success from do_replace()
Added replace_add_work() in commit f40a63b15c563 to support
replacement node and the partner node. But this function returns
0 for user input and 1 for success which caused do_replace()
returns 1. This patch fixes the problem with return 0.
Fixes: f40a63b15c563 ("drmgr/pci: Add multipath partner device support for hotplug replace")
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/drslot_chrp_pci.c b/src/drmgr/drslot_chrp_pci.c
index 4c41fcd..91c08e9 100644
--- a/src/drmgr/drslot_chrp_pci.c
+++ b/src/drmgr/drslot_chrp_pci.c
@@ -1051,9 +1051,10 @@ static int do_replace(struct dr_node *all_nodes)
}
usr_prompt = prompt_save;
+ return rc;
}
- return rc;
+ return 0;
}
int valid_pci_options(void)

View File

@ -0,0 +1,195 @@
commit 908986e43b6c67288aa084fe13155964caa807a8
Author: Haren Myneni <haren@linux.ibm.com>
Date: Sat May 16 11:34:22 2026 -0700
drmgr: Add NUMA based CPU removal
The current CPU removal process reads CPU list from last CPU and
remove CPUs based on the userspace request. This process can
result in CPU less NUMA nodes even though these nodes have more
memory which can affect on the system performance.
This patch adds NUMA aware CPU removal process to remove CPUs from
specific NUMA nodes and maintains NUMA balance. The selection of
node from which the CPU to be removed is based on the available
memory per CPU in that node called node ratio. So CPU is selected
from the node which has lower ratio.
If the NUMA topology can't be read, fallback using the current
process.
The node selection process is as follows:
- For each CPU removal request, update node ratios and sort the list.
- Select the next removable CPU from the dr_info CPU list and it
should belong to the first node.
- CPU associated to memory less nodes is considered first and then
the first node that has memory in the list.
- Repeat all CPUs in dr_info list until the next removable CPU is
matched with node CPU bitmap.
- The total number of CPU threads in the selected node is
decremented and cleared in the node CPU bitmap.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/drslot_chrp_cpu.c b/src/drmgr/drslot_chrp_cpu.c
index e367634..60956a0 100644
--- a/src/drmgr/drslot_chrp_cpu.c
+++ b/src/drmgr/drslot_chrp_cpu.c
@@ -164,6 +164,141 @@ static struct dr_node *get_available_cpu_by_index(struct dr_info *dr_info)
return cpu;
}
+/*
+ * Return node if CPU ID matches in node CPU bitmap.
+ */
+static struct ppcnuma_node *match_cpu_node(struct ppcnuma_node *node,
+ struct dr_node *cpu)
+{
+ int nid;
+
+ if (cpu->cpu_threads) {
+ nid = numa_node_of_cpu(cpu->cpu_threads->id);
+ if (nid == node->node_id) {
+ if (numa_bitmask_isbitset(node->cpus,
+ cpu->cpu_threads->id))
+ return node;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Return node if CPU belongs to any memoryless NUMA node.
+ */
+static struct ppcnuma_node *find_cpu_memless_node(struct dr_node *cpu)
+{
+ struct ppcnuma_node *node = NULL;
+ int nid;
+
+ ppcnuma_foreach_node(&numa, nid, node) {
+ if (node->n_lmbs)
+ continue;
+
+ if (match_cpu_node(node, cpu))
+ return node;
+ }
+
+ return NULL;
+}
+
+/*
+ * The node list is sorted by node ratio (less memory per CPU).
+ * So consider the first node
+ * Return node if CPU belongs to the first NUMA node which
+ * has memory.
+ */
+static struct ppcnuma_node *find_cpu_numa_node(struct dr_node *cpu)
+{
+ struct ppcnuma_node *node = NULL;
+ int found = 0;
+
+ ppcnuma_foreach_node_by_ratio(&numa, node) {
+ if (node->n_cpus && node->n_lmbs) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found && match_cpu_node(node, cpu))
+ return node;
+
+ return NULL;
+}
+
+/*
+ * Calculate node ratio based on amount of memory per CPU and sort
+ * the node ratio list.
+ */
+static void cpu_update_node_ratio(void)
+{
+ struct ppcnuma_node *node;
+ int nid;
+
+ ppcnuma_foreach_node(&numa, nid, node) {
+ if (!node->n_lmbs || !node->n_cpus)
+ continue;
+
+ /*
+ * Node ratio = n_lmbs per CPU
+ */
+ node->ratio = (node->n_lmbs * 100) / node->n_cpus;
+ }
+
+ order_numa_node_ratio_list();
+}
+
+/*
+ * Scan CPUs from the last one in the list and select the first CPU
+ * based on:
+ * - CPU from memory less node
+ * - If no CPUs are available in memory less nodes, CPU belongs to
+ * the first node from node ratio list.
+ */
+static struct dr_node *numa_get_next_cpu(struct dr_info *dr_info)
+{
+ struct ppcnuma_node *node;
+ struct dr_node *cpu = NULL;
+ struct thread *t;
+ int i, found = 0;
+
+ /*
+ * Update node ratio for each CPU removal request
+ */
+ cpu_update_node_ratio();
+
+ /* Find the first cpu with an online thread */
+ for (cpu = dr_info->all_cpus; cpu; cpu = cpu->next) {
+ if (cpu->unusable)
+ continue;
+
+ if (numa.memless_cpu_count)
+ node = find_cpu_memless_node(cpu);
+ else
+ node = find_cpu_numa_node(cpu);
+
+ if (!node)
+ continue;
+
+ t = cpu->cpu_threads;
+ for (i = 0; i < cpu->cpu_nthreads && t; i++, t = t->next) {
+ if (get_thread_state(t) == ONLINE)
+ found = 1;
+ numa_bitmask_clearbit(node->cpus, t->id);
+ }
+ if (found) {
+ node->n_cpus -= cpu->cpu_nthreads;
+ numa.cpu_count -= cpu->cpu_nthreads;
+ if (!node->n_lmbs)
+ numa.memless_cpu_count -= cpu->cpu_nthreads;
+ return cpu;
+ }
+ }
+
+ return NULL;
+}
+
/*
* Scan all CPUs from the last one for the next available CPU.
* Used only for non-NUMA based CPU removal.
@@ -202,8 +337,12 @@ static struct dr_node *get_next_available_cpu(struct dr_info *dr_info)
cpu = survivor;
} else if (usr_action == REMOVE) {
- /* Find the first cpu with an online thread */
- cpu = get_next_cpu(dr_info);
+ if (numa_enabled)
+ /* Find the first CPU from NUMA nodes */
+ cpu = numa_get_next_cpu(dr_info);
+ else
+ /* Find the first cpu with an online thread */
+ cpu = get_next_cpu(dr_info);
}
if (!cpu)

View File

@ -0,0 +1,117 @@
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;
}

View File

@ -0,0 +1,70 @@
commit fc252eaf3f1e2b6dcf2a646459ac7399db0ab18d
Author: Haren Myneni <haren@linux.ibm.com>
Date: Sat May 16 11:34:19 2026 -0700
drmgr: Add get_next_cpu() to identify the removable CPU
Move code which identifies the removable CPU to get_next_cpu().
This function is used only for the current non-numa based CPU
removal but helps to add for NUMA based CPU removal code in later
patch.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/drslot_chrp_cpu.c b/src/drmgr/drslot_chrp_cpu.c
index 3ef24f4..6a21663 100644
--- a/src/drmgr/drslot_chrp_cpu.c
+++ b/src/drmgr/drslot_chrp_cpu.c
@@ -160,11 +160,33 @@ static struct dr_node *get_available_cpu_by_index(struct dr_info *dr_info)
return cpu;
}
+/*
+ * Scan all CPUs from the last one for the next available CPU.
+ * Used only for non-NUMA based CPU removal.
+ */
+static struct dr_node *get_next_cpu(struct dr_info *dr_info)
+{
+ struct dr_node *cpu = NULL;
+ struct thread *t;
+
+ /* Find the first cpu with an online thread */
+ for (cpu = dr_info->all_cpus; cpu; cpu = cpu->next) {
+ if (cpu->unusable)
+ continue;
+
+ for (t = cpu->cpu_threads; t; t = t->next) {
+ if (get_thread_state(t) == ONLINE)
+ return cpu;
+ }
+ }
+
+ return NULL;
+}
+
static struct dr_node *get_next_available_cpu(struct dr_info *dr_info)
{
struct dr_node *cpu = NULL;
struct dr_node *survivor = NULL;
- struct thread *t;
if (usr_action == ADD) {
for (cpu = dr_info->all_cpus; cpu; cpu = cpu->next) {
@@ -177,15 +199,7 @@ static struct dr_node *get_next_available_cpu(struct dr_info *dr_info)
cpu = survivor;
} else if (usr_action == REMOVE) {
/* Find the first cpu with an online thread */
- for (cpu = dr_info->all_cpus; cpu; cpu = cpu->next) {
- if (cpu->unusable)
- continue;
-
- for (t = cpu->cpu_threads; t; t = t->next) {
- if (get_thread_state(t) == ONLINE)
- return cpu;
- }
- }
+ cpu = get_next_cpu(dr_info);
}
if (!cpu)

View File

@ -0,0 +1,106 @@
commit 1dee26c2a60dd9a5264331cc20143a5590289187
Author: Haren Myneni <haren@linux.ibm.com>
Date: Mon May 18 22:37:53 2026 -0700
drmgr: Add timeout signal handling for NUMA memory REMOVE
RMC expects drmgr timeout based on value passed with -w option and
drmgr can check fequently for each LMB removal request and exits
once reached the timeout value. But this check happens only in the
user space and does not consider when executes in the kernel to
remove memory. In the case of LMB removal, the kernel expects to
run longer until all pages in LMB are isolated and can return to
the user space for any pending signals.
This patch enables SIGALRM signal based on the user defined
value which generates signal when the timer expires. It allows
the kernel interface returns in case [age isolation is taking
longer and drmgr timeout.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c
index fe04ad1..5a08839 100644
--- a/src/drmgr/drslot_chrp_mem.c
+++ b/src/drmgr/drslot_chrp_mem.c
@@ -26,6 +26,9 @@
#include <dirent.h>
#include <inttypes.h>
#include <time.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdbool.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include "dr.h"
@@ -35,6 +38,7 @@
uint64_t block_sz_bytes = 0;
static char *state_strs[] = {"offline", "online"};
+sig_atomic_t numa_mem_timeout = 0;
static char *usagestr = "-c mem {-a | -r} {-q <quantity> -p {variable_weight | ent_capacity} | {-q <quantity> | -s [<drc_name> | <drc_index>]}}";
@@ -50,6 +54,14 @@ mem_usage(char **pusage)
*pusage = usagestr;
}
+/*
+ * SIGALRM handler for drmgr timeout
+ */
+void mem_timeout_handler(int sig)
+{
+ numa_mem_timeout = 1;
+}
+
/**
* report_resource_count
* @brief Report the number of LMBs that were added or removed.
@@ -1681,13 +1693,45 @@ static void clear_numa_lmb_links(void)
node->lmbs = NULL;
}
+/*
+ * Setup SIGALRM signal based on timeout value passed by the user
+ * (with -w option). In the case of LMB removal, the kernel
+ * interface can run longer until all pages in LMB are isolated
+ * and can return to the user space if any pending signals.
+ * This SIGALRM signal can exit the kernel in case LMB removal
+ * is taking longer than timeout.
+ */
+static int drmem_timer_setup(void)
+{
+ struct sigaction sigact;
+
+ if (!usr_timeout)
+ return 0;
+
+ sigact.sa_handler = mem_timeout_handler;
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = 0;
+ if (sigaction(SIGALRM, &sigact, NULL))
+ return -1;
+
+ alarm(usr_timeout);
+ return 0;
+}
+
static int numa_based_remove(uint32_t count)
{
struct lmb_list_head *lmb_list;
struct ppcnuma_node *node;
- int nid;
+ int nid, rc = 0;
uint32_t done = 0;
+ /*
+ * Enable alarm signal handler for usr_timeout
+ */
+ rc = drmem_timer_setup();
+ if (rc)
+ return rc;
+
/*
* Read the LMBs
* Link the LMBs to their node

View File

@ -0,0 +1,116 @@
commit 1c4812fb35510c7e02ff27fc39badbe5eef24611
Author: Haren Myneni <haren@linux.ibm.com>
Date: Sat May 16 11:34:20 2026 -0700
drmgr: Allocate CPU bitmap for each NUMA node
The current code allocates one bitmap and uses it to determine
number of valid CPUs for each NUMA node and then frees the bitmap.
The NUMA based CPU removal needs this bitmap per node to determine
the valid CPU in that node. So this patch retains bitmap per node
and frees it after DLPAR memory / CPU removal.
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.c b/src/drmgr/common_numa.c
index 6bc2ea8..eba6c3d 100644
--- a/src/drmgr/common_numa.c
+++ b/src/drmgr/common_numa.c
@@ -84,9 +84,6 @@ static int read_numa_topology(struct ppcnuma_topology *numa)
rc = 0;
- /* In case of allocation error, the libnuma is calling exit() */
- cpus = numa_allocate_cpumask();
-
for (nid = 0; nid <= max_node; nid++) {
if (!numa_bitmask_isbitset(numa_nodes_ptr, nid))
@@ -98,20 +95,24 @@ static int read_numa_topology(struct ppcnuma_topology *numa)
break;
}
+ /* In case of allocation error, the libnuma is calling exit() */
+ cpus = numa_allocate_cpumask();
+
rc = numa_node_to_cpus(nid, cpus);
- if (rc < 0)
+ if (rc < 0) {
+ numa_bitmask_free(cpus);
break;
+ }
/* Count the CPUs in that node */
for (i = 0; i < cpus->size; i++)
if (numa_bitmask_isbitset(cpus, i))
node->n_cpus++;
+ node->cpus = cpus;
numa->cpu_count += node->n_cpus;
}
- numa_bitmask_free(cpus);
-
if (rc) {
ppcnuma_foreach_node(numa, nid, node)
node->n_cpus = 0;
@@ -160,6 +161,20 @@ void build_numa_topology(void)
numa_enabled = 1;
}
+void free_numa_topology(void)
+{
+ struct ppcnuma_node *node;
+ int nid;
+
+ ppcnuma_foreach_node(&numa, nid, node) {
+ if (node) {
+ if (node->cpus)
+ numa_bitmask_free(node->cpus);
+ free(node);
+ }
+ }
+}
+
void order_numa_node_ratio_list(void)
{
int nid;
diff --git a/src/drmgr/common_numa.h b/src/drmgr/common_numa.h
index 2b0901e..7aea026 100644
--- a/src/drmgr/common_numa.h
+++ b/src/drmgr/common_numa.h
@@ -30,6 +30,7 @@ struct ppcnuma_node {
unsigned int ratio;
struct dr_node *lmbs; /* linked by lmb_numa_next */
struct ppcnuma_node *ratio_next;
+ struct bitmask *cpus;
};
struct ppcnuma_topology {
@@ -48,6 +49,7 @@ extern int numa_enabled;
extern struct ppcnuma_topology numa;
void build_numa_topology(void);
void order_numa_node_ratio_list(void);
+void free_numa_topology(void);
struct ppcnuma_node *ppcnuma_fetch_node(struct ppcnuma_topology *numa,
int node_id);
diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c
index 2d22bff..fe04ad1 100644
--- a/src/drmgr/drslot_chrp_mem.c
+++ b/src/drmgr/drslot_chrp_mem.c
@@ -1731,9 +1731,10 @@ int do_mem_kernel_dlpar(void)
if (usr_action == REMOVE && usr_drc_count && !usr_drc_index) {
build_numa_topology();
if (numa_enabled) {
- if (!numa_based_remove(usr_drc_count))
+ rc = numa_based_remove(usr_drc_count);
+ free_numa_topology();
+ if (!rc)
return 0;
-
/*
* If the NUMA based removal failed, lets try the legacy
* way.

View File

@ -0,0 +1,28 @@
commit 3a7d0b61e7a5f364660007a45cc9dcf1c3cb5ab4
Author: Haren Myneni <haren@linux.ibm.com>
Date: Mon May 18 22:37:52 2026 -0700
drmgr: Allow signals mentioned in new sigset_t
The current code uses sigdelset() to unblock some signals such as
SIGBUS, SIGALRM, and etc. But sigprocmask() with SIG_BLOCK sets
the union of this new set and the current sigset which ends up
blocking some of them (Ex: SIGALRM). Insted of using SIG_BLOCK,
SIG_SETMASK allows to use the complete new sigset_t.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/common.c b/src/drmgr/common.c
index 70f4dfd..68041a9 100644
--- a/src/drmgr/common.c
+++ b/src/drmgr/common.c
@@ -939,7 +939,7 @@ sig_setup(void)
sigdelset(&sigset, SIGABRT);
/* Now block all remaining signals */
- rc = sigprocmask(SIG_BLOCK, &sigset, NULL);
+ rc = sigprocmask(SIG_SETMASK, &sigset, NULL);
if (rc)
return -1;

View File

@ -0,0 +1,87 @@
commit 7926241f576de24df8b342858f5278911e035658
Author: Haren Myneni <haren@linux.ibm.com>
Date: Mon May 18 22:37:54 2026 -0700
drmgr: Do not remove LMBs when the timer expires
The current code selects LMBs from all NUMA node based on node
ratio and removes them until reaches the the requested limit. This
patch stops removing LMBs when receives SIGALRM signal based on
the user defined timeout.
Also reports total numaber of LMBs removed with DR_TOTAL_RESOURCES
to RMC even for partial memory removal or with an error.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c
index 5a08839..4a3fe3a 100644
--- a/src/drmgr/drslot_chrp_mem.c
+++ b/src/drmgr/drslot_chrp_mem.c
@@ -1478,6 +1478,9 @@ static int remove_lmb_from_node(struct ppcnuma_node *node, uint32_t count)
count, node->n_lmbs, node->node_id);
for (lmb = node->lmbs; lmb && done < count; lmb = lmb->lmb_numa_next) {
+ if (numa_mem_timeout)
+ break;
+
unlinked++;
err = remove_lmb_by_index(lmb->drc_index);
if (err)
@@ -1563,6 +1566,9 @@ static int remove_cpuless_lmbs(uint32_t count)
this_loop = 0;
ppcnuma_foreach_node(&numa, nid, node) {
+ if (numa_mem_timeout)
+ break;
+
if (!node->n_lmbs || node->n_cpus)
continue;
@@ -1656,6 +1662,9 @@ static int remove_cpu_lmbs(uint32_t count)
this_loop = 0;
ppcnuma_foreach_node_by_ratio(&numa, node) {
+ if (numa_mem_timeout)
+ break;
+
if (!node->n_lmbs || !node->n_cpus)
continue;
@@ -1739,14 +1748,13 @@ static int numa_based_remove(uint32_t count)
*/
lmb_list = get_lmbs(LMB_NORMAL_SORT);
if (lmb_list == NULL) {
- clear_numa_lmb_links();
- return -1;
+ rc = -1;
+ goto out_clear;
}
if (!numa.node_count) {
- clear_numa_lmb_links();
- free_lmbs(lmb_list);
- return -EINVAL;
+ rc = -EINVAL;
+ goto out_free;
}
ppcnuma_foreach_node(&numa, nid, node) {
@@ -1759,11 +1767,12 @@ static int numa_based_remove(uint32_t count)
done += remove_cpu_lmbs(count);
- report_resource_count(done);
-
- clear_numa_lmb_links();
+out_free:
free_lmbs(lmb_list);
- return 0;
+out_clear:
+ clear_numa_lmb_links();
+ report_resource_count(done);
+ return rc;
}
int do_mem_kernel_dlpar(void)

View File

@ -0,0 +1,150 @@
commit 27dd4cce01450d94ab58fa2e632eac34307a4a82
Author: Haren Myneni <haren@linux.ibm.com>
Date: Sat May 16 11:34:17 2026 -0700
drmgr: Move numa_topology code to common_numa.c
Move build_numa_topology and sort NUMA node ratio list code to
common_numa.c. These functions will also be used for NUMA aware
CPU removal in later patch.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/common_numa.c b/src/drmgr/common_numa.c
index 898aab6..6bc2ea8 100644
--- a/src/drmgr/common_numa.c
+++ b/src/drmgr/common_numa.c
@@ -27,6 +27,9 @@
#include "drmem.h" /* for DYNAMIC_RECONFIG_MEM */
#include "common_numa.h"
+int numa_enabled = 0;
+struct ppcnuma_topology numa;
+
struct ppcnuma_node *ppcnuma_fetch_node(struct ppcnuma_topology *numa, int nid)
{
struct ppcnuma_node *node;
@@ -118,7 +121,7 @@ static int read_numa_topology(struct ppcnuma_topology *numa)
return rc;
}
-int ppcnuma_get_topology(struct ppcnuma_topology *numa)
+static int ppcnuma_get_topology(struct ppcnuma_topology *numa)
{
int rc;
@@ -145,3 +148,35 @@ int ppcnuma_get_topology(struct ppcnuma_topology *numa)
return 0;
}
+
+void build_numa_topology(void)
+{
+ int rc;
+
+ rc = ppcnuma_get_topology(&numa);
+ if (rc)
+ return;
+
+ numa_enabled = 1;
+}
+
+void order_numa_node_ratio_list(void)
+{
+ int nid;
+ struct ppcnuma_node *node, *n, **p;
+
+ numa.ratio = NULL;
+
+ /* Create an ordered link of the nodes */
+ ppcnuma_foreach_node(&numa, nid, node) {
+ if (!node->n_lmbs || !node->n_cpus)
+ continue;
+
+ p = &numa.ratio;
+ for (n = numa.ratio;
+ n && n->ratio < node->ratio; n = n->ratio_next)
+ p = &n->ratio_next;
+ *p = node;
+ node->ratio_next = n;
+ }
+}
diff --git a/src/drmgr/common_numa.h b/src/drmgr/common_numa.h
index c209a3e..2b0901e 100644
--- a/src/drmgr/common_numa.h
+++ b/src/drmgr/common_numa.h
@@ -44,7 +44,11 @@ struct ppcnuma_topology {
struct assoc_arrays aa;
};
-int ppcnuma_get_topology(struct ppcnuma_topology *numa);
+extern int numa_enabled;
+extern struct ppcnuma_topology numa;
+void build_numa_topology(void);
+void order_numa_node_ratio_list(void);
+
struct ppcnuma_node *ppcnuma_fetch_node(struct ppcnuma_topology *numa,
int node_id);
diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c
index 4a36c73..eb75ccf 100644
--- a/src/drmgr/drslot_chrp_mem.c
+++ b/src/drmgr/drslot_chrp_mem.c
@@ -38,9 +38,6 @@ static char *state_strs[] = {"offline", "online"};
static char *usagestr = "-c mem {-a | -r} {-q <quantity> -p {variable_weight | ent_capacity} | {-q <quantity> | -s [<drc_name> | <drc_index>]}}";
-static struct ppcnuma_topology numa;
-static int numa_enabled = 0;
-
/**
* mem_usage
* @brief return usage string
@@ -1605,7 +1602,7 @@ static int remove_cpuless_lmbs(uint32_t count)
static void update_node_ratio(void)
{
int nid;
- struct ppcnuma_node *node, *n, **p;
+ struct ppcnuma_node *node;
uint32_t cpu_ratio, mem_ratio;
/*
@@ -1626,18 +1623,7 @@ static void update_node_ratio(void)
node->ratio = (cpu_ratio * 9 + mem_ratio) / 10;
}
- /* Create an ordered link of the nodes */
- ppcnuma_foreach_node(&numa, nid, node) {
- if (!node->n_lmbs || !node->n_cpus)
- continue;
-
- p = &numa.ratio;
- for (n = numa.ratio;
- n && n->ratio < node->ratio; n = n->ratio_next)
- p = &n->ratio_next;
- *p = node;
- node->ratio_next = n;
- }
+ order_numa_node_ratio_list();
}
/*
@@ -1693,17 +1679,6 @@ static int remove_cpu_lmbs(uint32_t count)
return done;
}
-static void build_numa_topology(void)
-{
- int rc;
-
- rc = ppcnuma_get_topology(&numa);
- if (rc)
- return;
-
- numa_enabled = 1;
-}
-
static void clear_numa_lmb_links(void)
{
int nid;

View File

@ -0,0 +1,81 @@
commit cbdbefdb8c82acae997cf1a30816e69b323f9979
Author: Haren Myneni <haren@linux.ibm.com>
Date: Sat May 16 11:34:18 2026 -0700
drmgr: Move read lmb-size property code to common_ofdt.c
get_dynamic_lmb_size() is used to get lmb size from "ibm,lmb-size"
property. This lmb size is needed to determine the number of LMBs
and used to find NUMA node ratio for NUMA aware memory and CPU
removal code. So move this function to common_ofdt.c
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/common_ofdt.c b/src/drmgr/common_ofdt.c
index 1e5fe53..0655559 100644
--- a/src/drmgr/common_ofdt.c
+++ b/src/drmgr/common_ofdt.c
@@ -28,6 +28,7 @@
#include <errno.h>
#include "dr.h"
#include "ofdt.h"
+#include "drmem.h"
#define RTAS_DIRECTORY "/proc/device-tree/rtas"
#define CHOSEN_DIRECTORY "/proc/device-tree/chosen"
@@ -932,3 +933,19 @@ int of_associativity_to_node(const char *dir, int min_common_depth)
return be32toh(prop[min_common_depth]);
}
+int get_dynamic_lmb_size(uint64_t *lmb_sz)
+{
+ int rc = 0;
+ uint64_t sz;
+
+ rc = get_property(DYNAMIC_RECONFIG_MEM, "ibm,lmb-size",
+ &sz, sizeof(sz));
+ if (rc) {
+ say(DEBUG, "Could not retrieve drconf LMB size\n");
+ return rc;
+ }
+
+ /* convert for LE systems */
+ *lmb_sz = be64toh(sz);
+ return 0;
+}
diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c
index eb75ccf..2d22bff 100644
--- a/src/drmgr/drslot_chrp_mem.c
+++ b/src/drmgr/drslot_chrp_mem.c
@@ -506,16 +506,9 @@ get_dynamic_reconfig_lmbs(struct lmb_list_head *lmb_list)
uint64_t lmb_sz;
int rc = 0;
- rc = get_property(DYNAMIC_RECONFIG_MEM, "ibm,lmb-size",
- &lmb_sz, sizeof(lmb_sz));
-
- /* convert for LE systems */
- lmb_sz = be64toh(lmb_sz);
-
- if (rc) {
- say(DEBUG, "Could not retrieve drconf LMB size\n");
+ rc = get_dynamic_lmb_size(&lmb_sz);
+ if (rc)
return rc;
- }
if (stat(DYNAMIC_RECONFIG_MEM_V1, &sbuf) == 0) {
rc = get_dynamic_reconfig_lmbs_v1(lmb_sz, lmb_list);
diff --git a/src/drmgr/ofdt.h b/src/drmgr/ofdt.h
index e9ebd03..c79ed65 100644
--- a/src/drmgr/ofdt.h
+++ b/src/drmgr/ofdt.h
@@ -185,6 +185,7 @@ int get_assoc_arrays(const char *dir, struct assoc_arrays *aa,
int min_common_depth);
int of_associativity_to_node(const char *dir, int min_common_depth);
int init_node(struct dr_node *);
+int get_dynamic_lmb_size(uint64_t *lmb_sz);
static inline int aa_index_to_node(struct assoc_arrays *aa, uint32_t aa_index)
{

View File

@ -0,0 +1,87 @@
commit 56f98cdf411196ea19336b3d5afe2382c596752a
Author: Srikar Dronamraju <srikar@linux.ibm.com>
Date: Thu Jul 17 20:10:17 2025 +0530
lparstat: Add Resource group monitoring support to lparstat
Resource groups is being introduced by PowerVM Hypervisor. System can
be partitioned into different resource groups. Resources are exclusive,
i.e they can be part of only one resource group at any point of time.
By default, all LPARs will be part of default resource group whose
resource group id will be 0. Once a resource group is created and
resources allocated for the resource group, these resources will be
removed from the default resource group. If a LPAR is moved to a
resource group, it can only use resources in that resource group.
Resource groups provides isolation because of which LPARs running one
resource group only contend with other LPARs in their resource group.
This is specifically true for shared LPARs, whose resources are now
being contained within the resource group they belong too.
When a resource group feature is available, this change
- Shows Resource Group Number to which this LPAR belongs to.
- Shows the current active processors in this resource group.
Example of an LPAR in a default resource group.
(lp3 being in default resource group)
lp3 $ lparstat -i | grep -i resource
lp3 $ ./src/lparstat -i | grep -i resource
Resource Group Number : 0
Active Processors in Resource Group : 50
lp3 $
Example of an LPAR in a non-default resource group.
(lp5 being part of non default resource group)
lp5 $ lparstat -i | grep -i resource
lp5 $ ./src/lparstat -i | grep -i resource
Resource Group Number : 1
Active Processors in Resource Group : 30
lp5 $
[Here ./src/lparstat refers to patched lparstat]
Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/man/lparstat.8 b/man/lparstat.8
index 76c46d2..ef20250 100644
--- a/man/lparstat.8
+++ b/man/lparstat.8
@@ -206,6 +206,12 @@ The memory group ID of the Workload Manager group that the LPAR belongs to.
.TP
Desired Variable Capacity Weight
The variable memory capacity weight of the LPAR.
+.TP
+Resource Group Number
+Identifier of Resource Group of Physical processors that this LPAR is a member of.
+.TP
+Active Processors in Resource Group
+Current number of active physical Processors in resource Group containing this LPAR.
.RE
.TP
\fB\-x\fR
diff --git a/src/lparstat.h b/src/lparstat.h
index 2e49044..9049b41 100644
--- a/src/lparstat.h
+++ b/src/lparstat.h
@@ -197,6 +197,10 @@ struct sysentry system_data[] = {
.descr = "Secondary VIOS Partition ID"},
{.name = "cmo_page_size",
.descr = "Physical Page Size"},
+ {.name = "resource_group_number",
+ .descr = "Resource Group Number"},
+ {.name = "resource_group_active_processors",
+ .descr = "Active Processors in Resource Group"},
/* /proc/meminfo */
{.name = "MemTotal",
@@ -344,6 +348,8 @@ char *iflag_entries[] = {
"unallocated_io_mapping_entitlement",
"entitled_memory_group_number",
"DesVarCapWt",
+ "resource_group_number",
+ "resource_group_active_processors",
NULL
};

View File

@ -0,0 +1,67 @@
commit cbc56e3b72f962d1ae91fa2a80b448a8b4b83a4d
Author: Srikar Dronamraju <srikar@linux.ibm.com>
Date: Thu Jul 17 20:10:16 2025 +0530
lparstat: print 'Maximum System Processors'
Maximum System Processors or Maximum Physical CPUs in System is not
getting reported in lparstat -i. Replace max_system_cpus with
system_potential_processors, since that's how Maximum Physical CPUs in
the system was being tracked in system_data
$ lparstat -i | grep "Maximum System Processors"
$ ./src/lparstat -i | grep "Maximum System Processors"
Maximum System Processors : 80
$
[Here ./src/lparstat refers to patched lparstat]
shared_cpus_in_system is same as
physical_procs_allocated_to_virtualization. shared_cpus_in_system was
not getting reported in lparstat -i. Commit 16e49f436470 ("lparstat:
print "Shared Physical CPUS in system" data") added
physical_procs_allocated_to_virtualization but didnt remove
shared_cpus_in_system. Hence clean it up.
Remove hypervisor_page_size, desired_virt_cpus, desired_memory,
desired_capacity, target_mem_factor, target_mem_size, since we are not
printing them anyway.
Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/lparstat.h b/src/lparstat.h
index 4260e1e..2e49044 100644
--- a/src/lparstat.h
+++ b/src/lparstat.h
@@ -326,10 +326,9 @@ char *iflag_entries[] = {
"MinEntCap",
"partition_max_entitled_capacity",
"CapInc",
- "max_system_cpus",
+ "system_potential_processors",
"system_active_processors",
"active_cpus_in_pool",
- "shared_cpus_in_system",
"physical_procs_allocated_to_virtualization",
"pool_capacity",
"entitled_proc_capacity_available",
@@ -341,16 +340,10 @@ char *iflag_entries[] = {
"entitled_memory_weight",
"entitled_memory_pool_number",
"entitled_memory_pool_size",
- "hypervisor_page_size",
- "unallocated_entitled_memory_weight",
+ "unallocated_entitled_memory_weight",
"unallocated_io_mapping_entitlement",
"entitled_memory_group_number",
- "desired_virt_cpus",
- "desired_memory",
"DesVarCapWt",
- "desired_capacity",
- "target_mem_factor",
- "target_mem_size",
NULL
};

View File

@ -0,0 +1,28 @@
commit 2959860a86b45cb4e42d968a06e24545cefb815c
Author: Tyrel Datwyler <tyreld@linux.ibm.com>
Date: Mon Oct 27 17:04:46 2025 -0700
lsslot: don't report an error for an empty PHB list
If a system has no PHB's currently assigned to the system then the dlpar
node list for PHB types will be empty/NULL. This is not intrisically an
error and therefore we should return a successful return code on exit if
there is nothing to list.
Return zero in place of -1 if the PHB node list is empty.
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/lsslot.c b/src/drmgr/lsslot.c
index 4bd50a9..5067b7c 100644
--- a/src/drmgr/lsslot.c
+++ b/src/drmgr/lsslot.c
@@ -674,7 +674,7 @@ int lsslot_chrp_phb(void)
phb_list = get_dlpar_nodes(PHB_NODES);
if (phb_list == NULL)
- return -1;
+ return 0;
/* display header */
printf("%-10s%-20s %s\n", "PHB name", "OFDT Name", "Slot(s) Connected");

View File

@ -0,0 +1,77 @@
commit 69168b726bf8de4fe43f8effe93811d087254faa
Author: Tyrel Datwyler <tyreld@linux.ibm.com>
Date: Mon Oct 27 16:55:50 2025 -0700
lsslot: remove instances of trailing whitespace
No functional change. Pedantic cleanup of all current instances of
trailing whitespace in the lsslot code.
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/lsslot.c b/src/drmgr/lsslot.c
index 83e9e85..4bd50a9 100644
--- a/src/drmgr/lsslot.c
+++ b/src/drmgr/lsslot.c
@@ -291,7 +291,7 @@ insert_print_node(struct dr_node *node)
print_list = pnode;
return;
}
-
+
if (loc_code_cmp(print_list->node->drc_name,
pnode->node->drc_name) > 0) {
/* The location code for the new node is less than that
@@ -328,7 +328,7 @@ insert_print_node(struct dr_node *node)
/**
* print_drslot_line
* @brief print a SLOT entry
- *
+ *
* @param pnode print_node to print
* @param fmt output format string
*/
@@ -349,7 +349,7 @@ print_drslot_line(struct print_node *pnode, char *fmt)
/* If no node info, then it is an empty node */
if (node->dev_type == HEA_DEV) {
struct dr_node *port = node->children;
-
+
if (!port) {
printf("Empty\n");
} else {
@@ -586,7 +586,7 @@ int lsslot_chrp_pci(void)
for (node = all_nodes; node; node = node->next) {
if (! node->is_owned || node->skip)
continue;
-
+
if (usr_drc_name) {
if (cmp_drcname(node->drc_name, usr_drc_name))
insert_print_node(node);
@@ -683,7 +683,7 @@ int lsslot_chrp_phb(void)
struct dr_node *child;
char *name;
int printed_count = 0;
-
+
if (usr_drc_name && strcmp(usr_drc_name, phb->drc_name))
continue;
@@ -804,7 +804,6 @@ int lsslot_chrp_mem(void)
if (lmb_list == NULL || lmb_list->lmbs == NULL)
return -1;
-
if (lmb_list->drconf_buf) {
print_drconf_mem(lmb_list);
} else {
@@ -825,7 +824,7 @@ int lsslot_chrp_mem(void)
printf("%-5s %c ", lmb->drc_name,
lmb->is_removable ? 'Y' : 'N');
-
+
for (scn = lmb->lmb_mem_scns; scn; scn = scn->next) {
if (first) {
printf(" %s",

View File

@ -0,0 +1,749 @@
commit e5fd24a6e35c3be78c96d6887e3774852bbe4674
Author: Aboorva Devarajan <aboorvad@linux.ibm.com>
Date: Wed Jan 1 22:56:07 2025 -0500
ppc64_cpu: Fix handling of non-contiguous CPU IDs
In ppc64le environments, adding or removing CPUs dynamically through
DLPAR can create gaps in CPU IDs, such as `0-103,120-151`, in this
case CPUs 104-119 are missing.
ppc64_cpu doesn't handles this scenario and always considers CPU IDs
to be contiguous causing issues in core numbering, cpu info and SMT
mode reporting.
To illustrate the issues this patch fixes, consider the following
system configuration:
$ lscpu
Architecture: ppc64le
Byte Order: Little Endian
CPU(s): 136
On-line CPU(s) list: 0-103,120-151
**Note: CPU IDs are non-contiguous**
-----------------------------------------------------------------
Before Patch:
-----------------------------------------------------------------
$ ppc64_cpu --info
Core 0: 0* 1* 2* 3* 4* 5* 6* 7*
Core 1: 8* 9* 10* 11* 12* 13* 14* 15*
Core 2: 16* 17* 18* 19* 20* 21* 22* 23*
Core 3: 24* 25* 26* 27* 28* 29* 30* 31*
Core 4: 32* 33* 34* 35* 36* 37* 38* 39*
Core 5: 40* 41* 42* 43* 44* 45* 46* 47*
Core 6: 48* 49* 50* 51* 52* 53* 54* 55*
Core 7: 56* 57* 58* 59* 60* 61* 62* 63*
Core 8: 64* 65* 66* 67* 68* 69* 70* 71*
Core 9: 72* 73* 74* 75* 76* 77* 78* 79*
Core 10: 80* 81* 82* 83* 84* 85* 86* 87*
Core 11: 88* 89* 90* 91* 92* 93* 94* 95*
Core 12: 96* 97* 98* 99* 100* 101* 102* 103*
........................................................... *gap*
Core 13: 120* 121* 122* 123* 124* 125* 126* 127*
Core 14: 128* 129* 130* 131* 132* 133* 134* 135*
Core 15: 136* 137* 138* 139* 140* 141* 142* 143*
Core 16: 144* 145* 146* 147* 148* 149* 150* 151*
**Although the CPU IDs are non contiguous, associated core IDs are
represented in contiguous order, which makes it harder to interpret
this clearly.**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ ppc64_cpu --cores-on
Number of cores online = 15
**Expected: Number of online cores = 17**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ ppc64_cpu --offline-cores
Cores offline = 13, 14
**Even though no cores are actually offline, two cores (13, 14)
are displayed as offline.**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ ppc64_cpu --online-cores
Cores online = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16
**The list of online cores is missing two cores (13, 14).**
-----------------------------------------------------------------
To resolve this, use the present CPU list from sysfs to assign
numbers to CPUs and cores, which will make this accurate.
$ cat /sys/devices/system/cpu/present
0-103,120-151
With this patch, the command output correctly reflects the
current CPU configuration, providing a more precise representation
of the system state.
-----------------------------------------------------------------
After Patch:
-----------------------------------------------------------------
$ ppc64_cpu --info
Core 0: 0* 1* 2* 3* 4* 5* 6* 7*
Core 1: 8* 9* 10* 11* 12* 13* 14* 15*
Core 2: 16* 17* 18* 19* 20* 21* 22* 23*
Core 3: 24* 25* 26* 27* 28* 29* 30* 31*
Core 4: 32* 33* 34* 35* 36* 37* 38* 39*
Core 5: 40* 41* 42* 43* 44* 45* 46* 47*
Core 6: 48* 49* 50* 51* 52* 53* 54* 55*
Core 7: 56* 57* 58* 59* 60* 61* 62* 63*
Core 8: 64* 65* 66* 67* 68* 69* 70* 71*
Core 9: 72* 73* 74* 75* 76* 77* 78* 79*
Core 10: 80* 81* 82* 83* 84* 85* 86* 87*
Core 11: 88* 89* 90* 91* 92* 93* 94* 95*
Core 12: 96* 97* 98* 99* 100* 101* 102* 103*
........................................................... *gap*
Core 15: 120* 121* 122* 123* 124* 125* 126* 127*
Core 16: 128* 129* 130* 131* 132* 133* 134* 135*
Core 17: 136* 137* 138* 139* 140* 141* 142* 143*
Core 18: 144* 145* 146* 147* 148* 149* 150* 151*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ ppc64_cpu --cores-on
Number of cores online = 17
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ ppc64_cpu --offline-cores
Cores offline =
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ ppc64_cpu --online-cores
Cores online = 0,1,2,3,4,5,6,7,8,9,10,11,12,15,16,17,18
-----------------------------------------------------------------
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
diff --git a/src/common/cpu_info_helpers.c b/src/common/cpu_info_helpers.c
index 756e792..e75cf6e 100644
--- a/src/common/cpu_info_helpers.c
+++ b/src/common/cpu_info_helpers.c
@@ -311,67 +311,94 @@ cleanup:
}
static void print_cpu_list(const cpu_set_t *cpuset, int cpuset_size,
- int cpus_in_system)
+ int threads_per_cpu)
{
- int core;
+ int *present_cores = NULL;
+ int num_present_cores;
+ int start, end, i = 0;
const char *comma = "";
- for (core = 0; core < cpus_in_system; core++) {
- int begin = core;
- if (CPU_ISSET_S(core, cpuset_size, cpuset)) {
- while (CPU_ISSET_S(core+1, cpuset_size, cpuset))
- core++;
+ if (get_present_core_list(&present_cores, &num_present_cores, threads_per_cpu) != 0) {
+ fprintf(stderr, "Failed to get present_cores list\n");
+ return;
+ }
- if (core > begin)
- printf("%s%d-%d", comma, begin, core);
- else
- printf("%s%d", comma, core);
+ while (i < num_present_cores) {
+ start = present_cores[i];
+ if (CPU_ISSET_S(start, cpuset_size, cpuset)) {
+ end = start;
+ while (i + 1 < num_present_cores &&
+ CPU_ISSET_S(present_cores[i + 1], cpuset_size, cpuset) &&
+ present_cores[i + 1] == end + 1) {
+ end = present_cores[++i];
+ }
+ if (start == end) {
+ printf("%s%d", comma, start);
+ } else {
+ printf("%s%d-%d", comma, start, end);
+ }
comma = ",";
}
+ i++;
}
+ free(present_cores);
}
-int __do_smt(bool numeric, int cpus_in_system, int threads_per_cpu,
- bool print_smt_state)
+int __do_smt(bool numeric, int cpus_in_system, int threads_per_cpu, bool print_smt_state)
{
- int thread, c, smt_state = 0;
cpu_set_t **cpu_states = NULL;
- int cpu_state_size = CPU_ALLOC_SIZE(cpus_in_system);
- int start_cpu = 0, stop_cpu = cpus_in_system;
+ int thread, smt_state = -1;
+ int cpu_state_size;
int rc = 0;
+ int i, core_id, threads_online;
+ int *present_cores = NULL;
+ int num_present_cores;
- cpu_states = (cpu_set_t **)calloc(threads_per_cpu, sizeof(cpu_set_t));
- if (!cpu_states)
+ if (get_present_core_list(&present_cores, &num_present_cores, threads_per_cpu) != 0) {
+ fprintf(stderr, "Failed to get present core list\n");
return -ENOMEM;
+ }
+ cpu_state_size = CPU_ALLOC_SIZE(num_present_cores);
+ cpu_states = (cpu_set_t **)calloc(threads_per_cpu, sizeof(cpu_set_t *));
+ if (!cpu_states) {
+ rc = -ENOMEM;
+ goto cleanup_present_cores;
+ }
for (thread = 0; thread < threads_per_cpu; thread++) {
- cpu_states[thread] = CPU_ALLOC(cpus_in_system);
+ cpu_states[thread] = CPU_ALLOC(num_present_cores);
+ if (!cpu_states[thread]) {
+ rc = -ENOMEM;
+ goto cleanup_cpu_states;
+ }
CPU_ZERO_S(cpu_state_size, cpu_states[thread]);
}
- for (c = start_cpu; c < stop_cpu; c++) {
- int threads_online = __get_one_smt_state(c, threads_per_cpu);
-
+ for (i = 0; i < num_present_cores; i++) {
+ core_id = present_cores[i];
+ threads_online = __get_one_smt_state(core_id, threads_per_cpu);
if (threads_online < 0) {
rc = threads_online;
- goto cleanup_get_smt;
+ goto cleanup_cpu_states;
+ }
+ if (threads_online) {
+ CPU_SET_S(core_id, cpu_state_size, cpu_states[threads_online - 1]);
}
- if (threads_online)
- CPU_SET_S(c, cpu_state_size,
- cpu_states[threads_online - 1]);
}
for (thread = 0; thread < threads_per_cpu; thread++) {
if (CPU_COUNT_S(cpu_state_size, cpu_states[thread])) {
- if (smt_state == 0)
+ if (smt_state == -1)
smt_state = thread + 1;
else if (smt_state > 0)
smt_state = 0; /* mix of SMT modes */
}
}
- if (!print_smt_state)
- return smt_state;
+ if (!print_smt_state) {
+ rc = smt_state;
+ goto cleanup_cpu_states;
+ }
if (smt_state == 1) {
if (numeric)
@@ -380,11 +407,9 @@ int __do_smt(bool numeric, int cpus_in_system, int threads_per_cpu,
printf("SMT is off\n");
} else if (smt_state == 0) {
for (thread = 0; thread < threads_per_cpu; thread++) {
- if (CPU_COUNT_S(cpu_state_size,
- cpu_states[thread])) {
+ if (CPU_COUNT_S(cpu_state_size, cpu_states[thread])) {
printf("SMT=%d: ", thread + 1);
- print_cpu_list(cpu_states[thread],
- cpu_state_size, cpus_in_system);
+ print_cpu_list(cpu_states[thread], cpu_state_size, threads_per_cpu);
printf("\n");
}
}
@@ -392,9 +417,12 @@ int __do_smt(bool numeric, int cpus_in_system, int threads_per_cpu,
printf("SMT=%d\n", smt_state);
}
-cleanup_get_smt:
+cleanup_cpu_states:
for (thread = 0; thread < threads_per_cpu; thread++)
CPU_FREE(cpu_states[thread]);
+ free(cpu_states);
+cleanup_present_cores:
+ free(present_cores);
return rc;
}
diff --git a/src/ppc64_cpu.c b/src/ppc64_cpu.c
index 4017240..0233d29 100644
--- a/src/ppc64_cpu.c
+++ b/src/ppc64_cpu.c
@@ -52,7 +52,6 @@
#define DSCR_DEFAULT_PATH "/sys/devices/system/cpu/dscr_default"
-#define MAX_NR_CPUS 1024
#define DIAGNOSTICS_RUN_MODE 42
#define CPU_OFFLINE -1
@@ -266,21 +265,31 @@ static int get_one_smt_state(int core)
static int get_smt_state(void)
{
int smt_state = -1;
- int i;
+ int i, rc;
+ int *present_cores;
+ int num_present_cores;
+
+ rc = get_present_core_list(&present_cores, &num_present_cores, threads_per_cpu);
+ if (rc != 0) {
+ return -1;
+ }
+
+ for (i = 0; i < num_present_cores; i++) {
+ int cpu_state = get_one_smt_state(present_cores[i]);
- for (i = 0; i < cpus_in_system; i++) {
- int cpu_state = get_one_smt_state(i);
if (cpu_state == 0)
continue;
if (smt_state == -1)
smt_state = cpu_state;
+
if (smt_state != cpu_state) {
smt_state = -1;
break;
}
}
+ free(present_cores);
return smt_state;
}
@@ -313,20 +322,36 @@ static int set_smt_state(int smt_state)
{
int i, j, rc = 0;
int error = 0;
+ int cpu_base, cpu_id, core_id;
+ int *present_cores = NULL;
+ int num_present_cores;
if (!sysattr_is_writeable("online")) {
perror("Cannot set smt state");
return -1;
}
- for (i = 0; i < threads_in_system; i += threads_per_cpu) {
+ rc = get_present_core_list(&present_cores, &num_present_cores, threads_per_cpu);
+
+ if (rc != 0) {
+ fprintf(stderr, "Failed to retrieve present core list\n");
+ return rc;
+ }
+
+ for (i = 0; i < num_present_cores; i++) {
+
+ core_id = present_cores[i];
+ cpu_base = core_id * threads_per_cpu;
+
/* Online means any thread on this core running, so check all
* threads in the core, not just the first. */
for (j = 0; j < threads_per_cpu; j++) {
- if (!cpu_online(i + j))
+ cpu_id = cpu_base + j;
+
+ if (!cpu_online(cpu_id))
continue;
- rc = set_one_smt_state(i, smt_state);
+ rc = set_one_smt_state(cpu_base, smt_state);
/* Record an error, but do not check result: if we
* have failed to set this core, keep trying
* subsequent ones. */
@@ -336,10 +361,13 @@ static int set_smt_state(int smt_state)
}
}
+ free(present_cores);
+
if (error) {
- fprintf(stderr, "One or more cpus could not be on/offlined\n");
+ fprintf(stderr, "One or more CPUs could not be on/offlined\n");
return -1;
}
+
return rc;
}
@@ -459,8 +487,8 @@ static int do_subcores_per_core(char *state)
}
printf("Subcores per core: %d\n", subcore_state);
} else {
- /* Kernel decides what values are valid, so no need to
- * check here. */
+ /* Kernel decides what values are valid, so no need to
+ * check here. */
subcore_state = strtol(state, NULL, 0);
rc = set_attribute(SYSFS_SUBCORES, "%d", subcore_state);
if (rc) {
@@ -1038,7 +1066,7 @@ static int set_all_threads_off(int cpu, int smt_state)
snprintf(path, SYSFS_PATH_MAX, SYSFS_CPUDIR"/%s", i, "online");
rc = offline_thread(path);
if (rc == -1)
- printf("Unable to take cpu%d offline", i);
+ printf("Unable to take CPU %d offline\n", i);
}
return rc;
@@ -1065,11 +1093,13 @@ static int set_one_core(int smt_state, int core, int state)
static int do_online_cores(char *cores, int state)
{
int smt_state;
- int *core_state, *desired_core_state;
+ int *core_state = NULL, *desired_core_state = NULL;
int i, rc = 0;
- int core;
+ int core, valid = 0, core_idx = 0;
char *str, *token, *end_token;
bool first_core = true;
+ int *present_cores = NULL;
+ int num_present_cores;
if (cores) {
if (!sysattr_is_writeable("online")) {
@@ -1083,49 +1113,62 @@ static int do_online_cores(char *cores, int state)
}
}
+ rc = get_present_core_list(&present_cores, &num_present_cores, threads_per_cpu);
+ if (rc != 0) {
+ fprintf(stderr, "Failed to retrieve present core list\n");
+ return rc;
+ }
+
smt_state = get_smt_state();
- core_state = calloc(cpus_in_system, sizeof(int));
- if (!core_state)
+ core_state = calloc(num_present_cores, sizeof(int));
+ if (!core_state) {
+ free(present_cores);
return -ENOMEM;
+ }
- for (i = 0; i < cpus_in_system ; i++)
- core_state[i] = (get_one_smt_state(i) > 0);
+ for (i = 0; i < num_present_cores; i++) {
+ core_state[i] = (get_one_smt_state(present_cores[i]) > 0);
+ }
if (!cores) {
printf("Cores %s = ", state == 0 ? "offline" : "online");
- for (i = 0; i < cpus_in_system; i++) {
+ for (i = 0; i < num_present_cores; i++) {
if (core_state[i] == state) {
if (first_core)
first_core = false;
else
printf(",");
- printf("%d", i);
+ printf("%d", present_cores[i]);
}
}
printf("\n");
free(core_state);
+ free(present_cores);
return 0;
}
if (smt_state == -1) {
printf("Bad or inconsistent SMT state: use ppc64_cpu --smt=on|off to set all\n"
- "cores to have the same number of online threads to continue.\n");
+ "cores to have the same number of online threads to continue.\n");
do_info();
+ free(present_cores);
return -1;
}
- desired_core_state = calloc(cpus_in_system, sizeof(int));
+ desired_core_state = calloc(num_present_cores, sizeof(int));
if (!desired_core_state) {
free(core_state);
+ free(present_cores);
return -ENOMEM;
}
- for (i = 0; i < cpus_in_system; i++)
+ for (i = 0; i < num_present_cores; i++) {
/*
* Not specified on command-line
*/
desired_core_state[i] = -1;
+ }
str = cores;
while (1) {
@@ -1141,42 +1184,57 @@ static int do_online_cores(char *cores, int state)
rc = -1;
continue;
}
- if (core >= cpus_in_system || core < 0) {
+
+ for (i = 0; i < num_present_cores; i++) {
+ if (core == present_cores[i]) {
+ valid = 1;
+ core_idx = i;
+ break;
+ }
+ }
+
+ if (!valid) {
printf("Invalid core to %s: %d\n", state == 0 ? "offline" : "online", core);
rc = -1;
continue;
}
- desired_core_state[core] = state;
+
+ desired_core_state[core_idx] = state;
}
if (rc) {
- free(core_state);
- free(desired_core_state);
- return rc;
+ goto cleanup;
}
- for (i = 0; i < cpus_in_system; i++) {
+ for (i = 0; i < num_present_cores; i++) {
if (desired_core_state[i] != -1) {
- rc = set_one_core(smt_state, i, state);
- if (rc)
+ rc = set_one_core(smt_state, present_cores[i], state);
+ if (rc) {
+ fprintf(stderr, "Failed to set core %d to %s\n", present_cores[i], state == 0 ? "offline" : "online");
break;
+ }
}
}
+cleanup:
free(core_state);
free(desired_core_state);
+ free(present_cores);
+
return rc;
}
static int do_cores_on(char *state)
{
int smt_state;
- int *core_state;
- int cores_now_online = 0;
- int i, rc;
+ int cores_now_online = 0, core_id = 0;
+ int i, rc = 0;
int number_to_have, number_to_change = 0, number_changed = 0;
+ int *core_state = NULL;
int new_state;
char *end_state;
+ int *present_cores = NULL;
+ int num_present_cores;
if (state) {
if (!sysattr_is_writeable("online")) {
@@ -1194,24 +1252,33 @@ static int do_cores_on(char *state)
if (!core_state)
return -ENOMEM;
- for (i = 0; i < cpus_in_system ; i++) {
- core_state[i] = (get_one_smt_state(i) > 0);
- if (core_state[i])
+ rc = get_present_core_list(&present_cores, &num_present_cores, threads_per_cpu);
+ if (rc != 0) {
+ fprintf(stderr, "Failed to retrieve present core list\n");
+ free(core_state);
+ return rc;
+ }
+ for (i = 0; i < num_present_cores; i++) {
+ int core = present_cores[i];
+ core_state[i] = (get_one_smt_state(core) > 0);
+ if (core_state[i]) {
cores_now_online++;
+ }
}
if (!state) {
printf("Number of cores online = %d\n", cores_now_online);
- free(core_state);
- return 0;
+ rc = 0;
+ goto cleanup;
}
smt_state = get_smt_state();
if (smt_state == -1) {
printf("Bad or inconsistent SMT state: use ppc64_cpu --smt=on|off to set all\n"
- "cores to have the same number of online threads to continue.\n");
+ "cores to have the same number of online threads to continue.\n");
do_info();
- return -1;
+ rc = -1;
+ goto cleanup;
}
if (!strcmp(state, "all")) {
@@ -1227,15 +1294,16 @@ static int do_cores_on(char *state)
}
if (number_to_have == cores_now_online) {
- free(core_state);
- return 0;
+ rc = 0;
+ goto cleanup;
}
- if (number_to_have > cpus_in_system) {
- printf("Cannot online more cores than are present.\n");
+ if (number_to_have <= 0 || number_to_have > cpus_in_system) {
+ printf("Error: Invalid number of cores requested: %d, possible values \
+ should be in range: (1-%d)\n", number_to_have, cpus_in_system);
do_cores_present();
- free(core_state);
- return -1;
+ rc = -1;
+ goto cleanup;
}
if (number_to_have > cores_now_online) {
@@ -1248,41 +1316,50 @@ static int do_cores_on(char *state)
if (new_state) {
for (i = 0; i < cpus_in_system; i++) {
+ core_id = present_cores[i];
if (!core_state[i]) {
- rc = set_one_core(smt_state, i, new_state);
- if (!rc)
+ rc = set_one_core(smt_state, core_id, new_state);
+ if (!rc) {
number_changed++;
- if (number_changed >= number_to_change)
+ }
+ if (number_changed >= number_to_change) {
break;
+ }
}
}
} else {
- for (i = cpus_in_system - 1; i > 0; i--) {
+ for (i = cpus_in_system - 1; i >= 0; i--) {
+ core_id = present_cores[i];
if (core_state[i]) {
- rc = set_one_core(smt_state, i, new_state);
- if (!rc)
+ rc = set_one_core(smt_state, core_id, new_state);
+ if (!rc) {
number_changed++;
- if (number_changed >= number_to_change)
+ }
+ if (number_changed >= number_to_change) {
break;
+ }
}
}
}
if (number_changed != number_to_change) {
cores_now_online = 0;
- for (i = 0; i < cpus_in_system ; i++) {
- if (cpu_online(i * threads_per_cpu))
+ for (i = 0; i < cpus_in_system; i++) {
+ core_id = present_cores[i];
+ if (cpu_online(core_id * threads_per_cpu)) {
cores_now_online++;
+ }
}
printf("Failed to set requested number of cores online.\n"
- "Requested: %d cores, Onlined: %d cores\n",
- number_to_have, cores_now_online);
- free(core_state);
- return -1;
+ "Requested: %d cores, Onlined: %d cores\n",
+ number_to_have, cores_now_online);
+ rc = -1;
}
+cleanup:
free(core_state);
- return 0;
+ free(present_cores);
+ return rc;
}
static bool core_is_online(int core)
@@ -1294,35 +1371,45 @@ static int do_info(void)
{
int i, j, thread_num;
char online;
- int core, subcores = 0;
+ int subcores = 0, core_id = 0;
+ int *present_cores = NULL;
+ int num_present_cores;
- if (is_subcore_capable())
+ if (is_subcore_capable()) {
subcores = num_subcores();
+ }
- for (i = 0, core = 0; core < cpus_in_system; i++) {
+ int rc = get_present_core_list(&present_cores, &num_present_cores, threads_per_cpu);
+ if (rc != 0) {
+ fprintf(stderr, "Failed to retrieve present core list\n");
+ return rc;
+ }
- if (!core_is_online(i))
+ for (i = 0; i < num_present_cores; i++) {
+ core_id = present_cores[i];
+ if (!core_is_online(core_id)) {
continue;
+ }
if (subcores > 1) {
- if (core % subcores == 0)
- printf("Core %3d:\n", core/subcores);
- printf(" Subcore %3d: ", core);
+ if (core_id % subcores == 0) {
+ printf("Core %3d:\n", core_id / subcores);
+ }
+ printf(" Subcore %3d: ", core_id);
} else {
- printf("Core %3d: ", core);
+ printf("Core %3d: ", core_id);
}
- thread_num = i * threads_per_cpu;
- for (j = 0; j < threads_per_cpu; j++, thread_num++) {
+ for (j = 0; j < threads_per_cpu; j++) {
+ thread_num = core_id * threads_per_cpu + j;
online = cpu_online(thread_num) ? '*' : ' ';
printf("%4d%c ", thread_num, online);
}
printf("\n");
- core++;
}
+ free(present_cores);
return 0;
}
-
static void usage(void)
{
printf(

View File

@ -0,0 +1,83 @@
commit 4cc6b27408f4a4097ad8f564cc11d1dfa46c9cf3
Author: Srikar Dronamraju <srikar@linux.ibm.com>
Date: Mon Sep 29 23:40:55 2025 +0530
smtstate: Start smtstate service after network target
While setting smtstate on boot, ppc64_cpu may fail to set smt mode if
there is pci probe happening which disables cpu hotplug.
smtstate[14016]: /sys/devices/system/cpu/smt/control: Device or resource busy
smtstate[14017]: Error updating SMT=4
systemd[1]: smtstate.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: smtstate.service: Failed with result 'exit-code'.
systemd[1]: Failed to start SMT automatic initialization service.
Here are traces from cpu_down_maps_locked showing cpu_hotplug_disabled=1
and cpu_down_maps_locked returning -EBUSY causing ppc64_cpu command to
fail while setting smt mode.
ppc64_cpu 6302 [037] 19.370155: probe:cpu_down_maps_locked: (c000000000160b18) cpu_hotplug_disabled=1
ppc64_cpu 6302 [037] 19.370164: probe:cpu_down_maps_locked__return: (c000000000160b18 <- c000000000162508) retval=0xfffffffffffffff0
At the time of ppc64_cpu failure, tracing cpu_hotplug_enable() shows the
likely reason why cpu_hotplug_disabled=1 (A network driver was trying to
probe a pci device).
(udev-worker) 5478 [016] 19.613108: probe:cpu_hotplug_enable: (c00000000015dba8)
c00000000015dba8 cpu_hotplug_enable+0x8 (/boot/vmlinux)
c0000000008fa7a8 pci_device_probe+0x1f8 (/boot/vmlinux)
c000000000a02440 really_probe+0x2f0 (/boot/vmlinux)
c000000000a0294c __driver_probe_device+0x1bc (/boot/vmlinux)
c000000000a029f0 driver_probe_device+0x60 (/boot/vmlinux)
c000000000a031f8 __driver_attach+0xf8 (/boot/vmlinux)
c0000000009fead4 bus_for_each_dev+0xb4 (/boot/vmlinux)
c000000000a01744 driver_attach+0x34 (/boot/vmlinux)
c000000000a00b18 bus_add_driver+0x218 (/boot/vmlinux)
c000000000a04278 driver_register+0x98 (/boot/vmlinux)
c0000000008f7d68 __pci_register_driver+0x68 (/boot/vmlinux)
c0080000fb98ee7c [unknown] ([i40e])
c000000000012690 do_one_initcall+0x60 (/boot/vmlinux)
c00000000027af94 do_init_module+0x84 (/boot/vmlinux)
c000000000278c0c load_module+0x2bfc (/boot/vmlinux)
c0000000002798e0 __do_sys_init_module+0x210 (/boot/vmlinux)
Hence to make smtstate more robust, this change ensures smtstate.service
is only called after network initialization and hence avoid all other
instances which could be disabling cpu_hotlug_disabled.
Similarly make smt_off service also more robust by ensuring its only called
after network initialization.
Suggested-by: Michal Suchanek <msuchanek@suse.d>
Suggested-by: "Nysal Jan K.A" <nysal@linux.ibm.com>
Suggested-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Signed-off-by: Srikar Dronamraju <srikar@linux.ibm.com>
Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/systemd/smt_off.service.in b/systemd/smt_off.service.in
index ed95945..e0c133e 100644
--- a/systemd/smt_off.service.in
+++ b/systemd/smt_off.service.in
@@ -1,6 +1,7 @@
[Unit]
Description=ppc64 set SMT off
Before=libvirt-bin.service
+After=network.target
[Service]
Type=oneshot
diff --git a/systemd/smtstate.service.in b/systemd/smtstate.service.in
index c285365..ba3f3d3 100644
--- a/systemd/smtstate.service.in
+++ b/systemd/smtstate.service.in
@@ -3,7 +3,7 @@ Description=SMT automatic initialization service
Documentation=man:smtstate(8)
Conflicts=shutdown.target
Before=shutdown.target
-After=sysinit.target
+After=network.target
DefaultDependencies=no
[Service]

View File

@ -0,0 +1,142 @@
The drmgr selects the removal LMB based on NUMA node ratio and
calls the kernel interface to remove the each selected LMB. Then
the kernel interface removes the LMB only after all pages are
isolated. But this page isolation can take longer which may affect
the memory removal process. The kernel interface returns to the
user space if sny signals are pending.
So do not allow the kernel interface execute more then 30 secs for
each LMB removal. Setup 30 secs timer and generate SIGUSR1 signal
for each kernel interface.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
src/drmgr/common.c | 1 +
src/drmgr/drslot_chrp_mem.c | 68 +++++++++++++++++++++++++++++++++----
2 files changed, 63 insertions(+), 6 deletions(-)
diff --git a/src/drmgr/common.c b/src/drmgr/common.c
index 68041a9..70f5d3b 100644
--- a/src/drmgr/common.c
+++ b/src/drmgr/common.c
@@ -937,6 +937,7 @@ sig_setup(void)
sigdelset(&sigset, SIGALRM);
sigdelset(&sigset, SIGQUIT);
sigdelset(&sigset, SIGABRT);
+ sigdelset(&sigset, SIGUSR1);
/* Now block all remaining signals */
rc = sigprocmask(SIG_SETMASK, &sigset, NULL);
diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c
index 4a3fe3a..ea8e8ce 100644
--- a/src/drmgr/drslot_chrp_mem.c
+++ b/src/drmgr/drslot_chrp_mem.c
@@ -39,6 +39,10 @@
uint64_t block_sz_bytes = 0;
static char *state_strs[] = {"offline", "online"};
sig_atomic_t numa_mem_timeout = 0;
+sig_atomic_t lmb_rm_timeout = 0;
+struct itimerspec lmb_tval;
+struct sigevent lmb_sevent;
+timer_t lmb_timer;
static char *usagestr = "-c mem {-a | -r} {-q <quantity> -p {variable_weight | ent_capacity} | {-q <quantity> | -s [<drc_name> | <drc_index>]}}";
@@ -62,6 +66,15 @@ void mem_timeout_handler(int sig)
numa_mem_timeout = 1;
}
+/*
+ * SIGUSR1 handler for LMB removal timeout and used
+ * only for NUMA based memory removal
+ */
+void lmb_rm_timeout_handler(int sig)
+{
+ if (sig == SIGUSR1) lmb_rm_timeout = 1;
+}
+
/**
* report_resource_count
* @brief Report the number of LMBs that were added or removed.
@@ -1461,12 +1474,36 @@ int valid_mem_options(void)
static int remove_lmb_by_index(uint32_t drc_index)
{
char cmdbuf[128];
- int offset;
+ int offset, rc;
offset = sprintf(cmdbuf, "memory remove index 0x%x", drc_index);
- return do_kernel_dlpar_common(cmdbuf, offset,
- 1 /* Don't report error */);
+ /*
+ * The kernel interface removes LMB only after all pages are
+ * isolated. So sometimes the kernel waits forever to isolate
+ * pages and the drmgr can not make any progress. The kernel
+ * returns to the user space for any pending signals.
+ *
+ * Setup 30 secs timer and generate SIGUSR1 signal in case
+ * the kernel request takes longer than 30 secs.
+ */
+ lmb_rm_timeout = 0;
+ lmb_tval.it_value.tv_sec = 30;
+ timer_settime(lmb_timer, 0, &lmb_tval, NULL);
+
+ rc = do_kernel_dlpar_common(cmdbuf, offset,
+ 1 /* Don't report error */);
+
+ if (!lmb_rm_timeout) {
+ /*
+ * Disable the timer if the kernel request returned before
+ * 30 secs interval.
+ */
+ lmb_tval.it_value.tv_sec = 0;
+ timer_settime(lmb_timer, 0, &lmb_tval, NULL);
+ }
+
+ return rc;
}
static int remove_lmb_from_node(struct ppcnuma_node *node, uint32_t count)
@@ -1707,12 +1744,30 @@ static void clear_numa_lmb_links(void)
* (with -w option). In the case of LMB removal, the kernel
* interface can run longer until all pages in LMB are isolated
* and can return to the user space if any pending signals.
- * This SIGALRM signal can exit the kernel in case LMB removal
- * is taking longer than timeout.
+ * It may cause drmgr waiting forever on 1 LMB removal and can not
+ * make progress further. So setup SIGUSR1 30 secs timer for each
+ * LMB kernel removal request.
+ *
+ * This SIGALRM signal is used to exit drmgr in case if the complete
+ * memory removal process takes longer than the timeout value.
*/
static int drmem_timer_setup(void)
{
- struct sigaction sigact;
+ struct sigaction sigact, lmb_sigact;
+
+ lmb_sigact.sa_handler = lmb_rm_timeout_handler;
+ sigemptyset(&lmb_sigact.sa_mask);
+ lmb_sigact.sa_flags = 0;
+ sigaction(SIGUSR1, &lmb_sigact, NULL);
+
+ lmb_sevent.sigev_notify = SIGEV_SIGNAL;
+ lmb_sevent.sigev_signo = SIGUSR1;
+ lmb_sevent.sigev_value.sival_ptr = &lmb_timer;
+ timer_create(CLOCK_MONOTONIC, &lmb_sevent, &lmb_timer);
+ lmb_tval.it_value.tv_sec = 30;
+ lmb_tval.it_value.tv_nsec = 0;
+ lmb_tval.it_interval.tv_sec = 0;
+ lmb_tval.it_interval.tv_nsec = 0;
if (!usr_timeout)
return 0;
@@ -1770,6 +1825,7 @@ static int numa_based_remove(uint32_t count)
out_free:
free_lmbs(lmb_list);
out_clear:
+ timer_delete(lmb_timer);
clear_numa_lmb_links();
report_resource_count(done);
return rc;

View File

@ -0,0 +1,47 @@
commit 4443a68d523043d69195e5a5a27fb9fc7ae8c50f
Author: Shrikanth Hegde <sshegde@linux.ibm.com>
Date: Mon Mar 10 22:29:16 2025 +0530
lparstat: print memory mode correctly (revised)
Starting from power10, active memory sharing(AMS) is not supported.
So from power10 onwards the H_GET_MPP hcall fails and hence
corresponding fields in lparcfg are not populated, such as
entitled_memory_pool_number etc.
Use HWCAP mechanism and print memory model as dedicated for power10
onwards.
Suggested-by: Peter Bergner <bergner@linux.ibm.com>
Signed-off-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/lparstat.c b/src/lparstat.c
index db22316..8eddd7c 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -37,6 +37,11 @@
#include "pseries_platform.h"
#include "cpu_info_helpers.h"
#include <time.h>
+#include <sys/auxv.h>
+
+#ifndef PPC_FEATURE2_ARCH_3_1
+#define PPC_FEATURE2_ARCH_3_1 0x00040000
+#endif
#define LPARCFG_FILE "/proc/ppc64/lparcfg"
#define SE_NOT_FOUND "???"
@@ -794,7 +799,11 @@ void get_memory_mode(struct sysentry *se, char *buf)
struct sysentry *tmp;
tmp = get_sysentry("entitled_memory_pool_number");
- if (atoi(tmp->value) == 65535)
+ /*
+ * from power10 onwards Active Memory Sharing(AMS) is not
+ * supported. Hence always display it as dedicated for those
+ */
+ if (atoi(tmp->value) == 65535 || (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_1))
sprintf(buf, "Dedicated");
else
sprintf(buf, "Shared");

View File

@ -1,44 +1,54 @@
Name: powerpc-utils Name: powerpc-utils
Version: 1.3.10 Version: 1.3.13
Release: 6%{?dist} Release: 5%{?dist}
Summary: PERL-based scripts for maintaining and servicing PowerPC systems Summary: PERL-based scripts for maintaining and servicing PowerPC systems
Group: System Environment/Base License: GPL-2.0-only
License: GPLv2 URL: https://github.com/ibm-power-utilities/powerpc-utils
URL: https://github.com/ibm-power-utilities/powerpc-utils Source0: https://github.com/ibm-power-utilities/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
Source0: https://github.com/ibm-power-utilities/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz Source1: nx-gzip.udev
Source1: nx-gzip.udev Patch: powerpc-utils-1.3.11-manpages.patch
Patch0: powerpc-utils-1.3.10-manpages.patch
Patch1: powerpc-utils-1.3.10-distro.patch
# bz#2121470, Fix lsslot -c mem output when using 4GB LMB size
Patch3: powerpc-utils-b1b9e7-LMB_size_4GB.patch
Patch4: powerpc-utils-e1f1de-lmb_address_in_hexadecimal.patch
Patch5: powerpc-utils-fix_setting_primary_slave_across_reboots.patch
Patch6: powerpc-utils-f4c2b0-fix_display_of_mode_for_dedicated_donating_partition.patch
# lparstat: Fix-negative-values-seen-while-running-lpar # upstream patches
Patch10: powerpc-utils-1.3.10-lparstat-Fix-negative-values-seen-while-running-lpar.patch Patch: powerpc-utils-1.3.13-cpu_info_helpers.patch
# report-mixed-SMT-state Patch: powerpc-utils-1.3.13-ppc64_cpu-Fix-handling-of-non-contiguous-CPU-IDs.patch
Patch11: powerpc-utils-1.3.10-lparstat-report-mixed-SMT-state.patch Patch: powerpc-utils-1.3.13-drmgr-return.patch
# Fix-offline-threads-uninitialized-entries Patch: powerpc-utils-lparstat-print-memory-mode-correctly.patch
Patch12: powerpc-utils-1.3.10-lparstat-Fix-offline-threads-uninitialized-entries.patch # Ability to display Resource group
Patch: powerpc-utils-1.3.13-smtstate_start_smtstate_service_after_network_target.patch
Patch: powerpc-utils-1.3.13-lsslot_remove_instances_of_trailing_whitespace.patch
Patch: powerpc-utils-1.3.13-lsslot_dont_report_an_error_for_an_empty_PHB_list.patch
Patch: powerpc-utils-1.3.13-lparstat_print_Maximum_System_Processors.patch
Patch: powerpc-utils-1.3.13-lparstat_Add_Resource_group_monitoring_support_to_lparstat.patch
# Dynamically removing cores from an LPAR is not taking care of NUMA topology (DLPAR)
Patch: powerpc-utils-1.3.13-drmgr_Move_numa_topology_code_to_common_numa.patch
Patch: powerpc-utils-1.3.13-drmgr_Move_read_lmb-size_property_code_to_common_ofdt.patch
Patch: powerpc-utils-1.3.13-drmgr_Add_get_next_cpu_to_identify_the_removable_CPU.patch
Patch: powerpc-utils-1.3.13-drmgr_Allocate_CPU_bitmap_for_each_NUMA_node.patch
Patch: powerpc-utils-1.3.13-drmgr_Add_NUMA_configuration_update_for_CPU_remove.patch
Patch: powerpc-utils-1.3.13-drmgr_Add_NUMA_based_CPU_removal.patch
# DLPAR Memory remove/add operations fail with SAP HANA DB loaded
Patch: powerpc-utils-1.3.13-drmgr_Allow_signals_mentioned_in_new_sigset_t.patch
Patch: powerpc-utils-1.3.13-drmgr_Add_timeout_signal_handling_for_NUMA_memory_REMOVE.patch
Patch: powerpc-utils-1.3.13-drmgr_Do_not_remove_LMBs_when_the_timer_expires.patch
Patch: powerpc-utils-1.3.13-use-30-secs-timeout-for-each-LMB-removal-kernel-interface.patch
ExclusiveArch: ppc %{power64} ExclusiveArch: ppc %{power64}
BuildRequires: gcc BuildRequires: gcc
BuildRequires: make BuildRequires: make
BuildRequires: automake BuildRequires: automake
BuildRequires: doxygen BuildRequires: doxygen
BuildRequires: zlib-devel BuildRequires: zlib-devel
BuildRequires: librtas-devel >= 1.4.0 BuildRequires: librtas-devel >= 1.4.0
BuildRequires: libservicelog-devel >= 1.0.1-2 BuildRequires: libservicelog-devel >= 1.0.1-2
BuildRequires: perl-generators BuildRequires: perl-generators
BuildRequires: systemd BuildRequires: systemd
BuildRequires: numactl-devel BuildRequires: numactl-devel
# rtas_dump explicit dependency # rtas_dump explicit dependency
Requires: perl(Data::Dumper) Requires: perl(Data::Dumper)
Requires: %{name}-core = %{version}-%{release} Requires: %{name}-core = %{version}-%{release}
%description %description
PERL-based scripts for maintaining and servicing PowerPC systems. PERL-based scripts for maintaining and servicing PowerPC systems.
@ -51,13 +61,22 @@ Requires(preun): systemd
Requires(postun): systemd Requires(postun): systemd
Requires: kmod Requires: kmod
Requires: which Requires: which
Requires: gawk Requires: /usr/bin/awk
Requires: bc Requires: /usr/bin/basename
Requires: findutils Requires: /usr/bin/bc
Requires: grep Requires: /usr/bin/cat
Requires: sed Requires: /usr/bin/cut
Requires: systemd-udev Requires: /usr/bin/echo
Requires: coreutils Requires: /usr/bin/find
Requires: /bin/grep
Requires: /usr/bin/head
Requires: /usr/bin/ls
Requires: /usr/bin/sed
Requires: /usr/bin/tr
Requires: /usr/bin/udevadm
# udev rule move
Conflicts: libnxz < 0.63-3
%description core %description core
Core utilities for maintaining and servicing PowerPC systems. Core utilities for maintaining and servicing PowerPC systems.
@ -66,12 +85,10 @@ Core utilities for maintaining and servicing PowerPC systems.
%prep %prep
%autosetup -p1 %autosetup -p1
%build %build
export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
./autogen.sh ./autogen.sh
%configure --with-systemd=%{_unitdir} --disable-werror %configure --with-systemd=%{_unitdir} --disable-werror
make %{?_smp_mflags} make %{?_smp_mflags} V=1
%install %install
@ -87,14 +104,11 @@ rm -rf $RPM_BUILD_ROOT/usr/share/doc/packages/powerpc-utils
rm -f $RPM_BUILD_ROOT%{_pkgdocdir}/COPYING rm -f $RPM_BUILD_ROOT%{_pkgdocdir}/COPYING
# install udev rule for the nx-gzip accelerator # install udev rule for the nx-gzip accelerator
install -pDm 644 %{SOURCE1} %{buildroot}%{_udevrulesdir}/90-nx-gzip.rules install -pDm 644 %{SOURCE1} %{buildroot}%{_udevrulesdir}/90-nx-gzip.rules
# remove init script and perl script. They are deprecated # remove init script and perl script. They are deprecated
rm -rf $RPM_BUILD_ROOT/etc/init.d/ibmvscsis.sh $RPM_BUILD_ROOT/usr/sbin/vscsisadmin rm -rf $RPM_BUILD_ROOT/etc/init.d/ibmvscsis.sh $RPM_BUILD_ROOT/usr/sbin/vscsisadmin
# nvsetenv is just a wrapper to nvram
ln -s nvram.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/nvsetenv.8.gz
# symlink uspchrp # symlink uspchrp
ln -s serv_config %{buildroot}%{_sbindir}/uspchrp ln -s serv_config %{buildroot}%{_sbindir}/uspchrp
ln -s serv_config.8 %{buildroot}%{_mandir}/man8/uspchrp.8 ln -s serv_config.8 %{buildroot}%{_mandir}/man8/uspchrp.8
@ -102,6 +116,12 @@ ln -s serv_config.8 %{buildroot}%{_mandir}/man8/uspchrp.8
# deprecated, use sosreport instead # deprecated, use sosreport instead
rm -f $RPM_BUILD_ROOT%{_sbindir}/snap $RPM_BUILD_ROOT%{_mandir}/man8/snap.8* rm -f $RPM_BUILD_ROOT%{_sbindir}/snap $RPM_BUILD_ROOT%{_mandir}/man8/snap.8*
# drop needless stuffs
rm -rf $RPM_BUILD_ROOT%{_prefix}/lib/powerpc-utils
# keep service name
mv $RPM_BUILD_ROOT%{_unitdir}/hcn-init-NetworkManager.service $RPM_BUILD_ROOT%{_unitdir}/hcn-init.service
%post core %post core
%systemd_post hcn-init.service %systemd_post hcn-init.service
# update the smt.state file with current SMT # update the smt.state file with current SMT
@ -121,18 +141,25 @@ systemctl enable hcn-init.service >/dev/null 2>&1 || :
%files %files
# PERL-based scripts for maintaining and servicing PowerPC systems # PERL-based scripts for maintaining and servicing PowerPC systems
%doc README Changelog %doc README Changelog
%license COPYING
%{_sbindir}/hvcsadmin %{_sbindir}/hvcsadmin
%{_sbindir}/rtas_dump %{_sbindir}/rtas_dump
%{_mandir}/man8/hvcsadmin.8* %{_mandir}/man8/hvcsadmin.8*
%{_mandir}/man8/rtas_dump.8* %{_mandir}/man8/rtas_dump.8*
%files core %files core
%doc README Changelog
%license COPYING %license COPYING
%dir %{_localstatedir}/lib/powerpc-utils %dir %{_localstatedir}/lib/powerpc-utils
%config(noreplace) %{_localstatedir}/lib/powerpc-utils/smt.state %verify(not md5 size mtime) %config(noreplace) %{_localstatedir}/lib/powerpc-utils/smt.state
%{_unitdir}/smtstate.service %{_unitdir}/smtstate.service
%{_unitdir}/smt_off.service %{_unitdir}/smt_off.service
%{_unitdir}/hcn-init.service %{_unitdir}/hcn-init.service
%if 0%{?wicked}
%{_unitdir}/hcn-init-wicked.service
%else
%exclude %{_unitdir}/hcn-init-wicked.service
%endif
%{_bindir}/amsstat %{_bindir}/amsstat
%{_sbindir}/activate_firmware %{_sbindir}/activate_firmware
%{_sbindir}/bootlist %{_sbindir}/bootlist
@ -201,123 +228,193 @@ systemctl enable hcn-init.service >/dev/null 2>&1 || :
%{_mandir}/man8/nvram.8* %{_mandir}/man8/nvram.8*
%{_mandir}/man8/ofpathname.8* %{_mandir}/man8/ofpathname.8*
%{_mandir}/man8/drmgr.8* %{_mandir}/man8/drmgr.8*
%{_mandir}/man8/drmgr-hooks.8*
%{_mandir}/man8/lparnumascore.8* %{_mandir}/man8/lparnumascore.8*
%changelog %changelog
* Wed Jul 26 2023 Than Ngo <than@redhat.com> - 1.3.10-6 * Thu Jul 16 2026 Than Ngo <than@redhat.com> - 1.3.13-5
- Resolves: RHEL-138523, Add ability to display Resource group
- 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
* Thu Jan 08 2026 Than Ngo <than@redhat.com> - 1.3.13-4
- Resolves: RHEL-128106, lparstat: print memory mode correctly
* Tue Apr 22 2025 Than Ngo <than@redhat.com> - 1.3.13-3
- Resolves: RHEL-81987, Fix return value for success from do_replace()
* Sat Feb 01 2025 Than Ngo <than@redhat.com> - 1.3.13-2
- Resolves: RHEL-76285, Fix handling of non-contiguous CPU IDs
* Wed Nov 20 2024 Than Ngo <than@redhat.com> - 1.3.13-1
- Update to 1.3.13
Resolves: RHEL-24535
* Mon Nov 18 2024 Than Ngo <than@redhat.com> - 1.3.12-7
- Add, multipath - drmgr support
- Fix, SMT state is not honored when new CPUs are added dynamically
Resolves: RHEL-62938
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 1.3.12-6
- Bump release for October 2024 mass rebuild:
Resolves: RHEL-64018
* Thu Jun 27 2024 Than Ngo <than@redhat.com> - 1.3.12-5
- add verify attributes for smt.state to ignore the verification
Related: RHEL-32262
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 1.3.12-4
- Bump release for June 2024 mass rebuild
* Tue Apr 09 2024 Than Ngo <than@redhat.com> - 1.3.12-3
- Resolves: RHEL-32262, update 1.3.12 for rhel-10
* Sun Apr 07 2024 Than Ngo <than@redhat.com> - 1.3.12-2
- conditionally hcn-init-wicked.service
* Fri Apr 05 2024 Than Ngo <than@redhat.com> - 1.3.12-1
- update to 1.3.12
* Fri Jan 26 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.11-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.11-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Tue Aug 01 2023 Than Ngo <than@redhat.com> - 1.3.11-4
- Fix negative values seen while running lpar - Fix negative values seen while running lpar
- Fix lparstat error with mixed SMT state - Fix lparstat error with mixed SMT state
Resolves: #2225135 - Fix negative values seen while running lparstat with -E option
* Sat Jun 17 2023 Than Ngo <than@redhat.com> - 1.3.10-5 * Fri Jul 21 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.11-3
- Resolves: #2207649, Add udev rule for the nx-gzip in to the core subpackage - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Tue Apr 25 2023 Than Ngo <than@redhat.com> - 1.3.10-4 * Thu Feb 16 2023 Than Ngo <than@redhat.com> - 1.3.11-2
- Resolves: #2166871, lparstat showing incorrect mode in a dedicated-donating LPAR - migrated to SPDX license
* Mon Nov 28 2022 Than Ngo <than@redhat.com> - 1.3.10-3 * Tue Jan 24 2023 Than Ngo <than@redhat.com> - 1.3.11-1
- Resolves: #2148878, HNV bond fails to come up with sriov interface as active slave - update to 1.3.11
* Fri Oct 21 2022 Than Ngo <than@redhat.com> - 1.3.10-2 * Fri Jan 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.10-6
- Resolves: #2121481, Fix lsslot -c mem output when using 4GB LMB size - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Mon Jun 06 2022 Than Ngo <than@redhat.com> - 1.3.10-1 * Wed Nov 02 2022 Than Ngo <than@redhat.com> - 1.3.10-5
- Resolves: #2051330, Linux Hybrid Network Virtualization update - Fix lsslot -c mem output when using 4GB LMB size
- Resolves: #2083469, smtstate --save command failed - Add NVMf-FC boot support for Power
* Fri May 13 2022 Than Ngo <than@redhat.com> - 1.3.9-3 * Fri Jul 22 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.10-4
- Resolves: #2059459, add new DRC type description strings for latest PCIe slot types - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
- Resolves: #2078514, Fix NM HNV setting primary slave
- Resolves: #2083469, smtstate test failed as smtstate --save command failed
* Thu Dec 09 2021 Than Ngo <than@redhat.com> - 1.3.9-1 * Tue Jun 14 2022 Jakub Čajka <jcajka@redhat.com> - 1.3.10-3
- Resolves: #2028690, rebase to 1.3.9 - Add udev rule for the nx-gzip in to the core subpackage
* Thu Dec 02 2021 Than Ngo <than@redhat.com> - 1.3.8-10 * Wed Jun 08 2022 Than Ngo <than@redhat.com> - 1.3.10-2
- Related: #2022225, increase release - install smt.state as config file
- drop nvsetenv which is included in upstream
* Thu Nov 11 2021 Than Ngo <than@redhat.com> - 1.3.8-9 * Fri Jun 03 2022 Than Ngo <than@redhat.com> - 1.3.10-1
- Resolves: #2022225, enable support vnic as backend for HNV interfaces - update to 1.3.10
* Thu Oct 07 2021 Than Ngo <than@redhat.com> - 1.3.8-8 * Thu May 12 2022 Than Ngo <than@redhat.com> - 1.3.9-6
- lsdevinfo: optimize criteria filtering - fix smtstate test failure, add default SMT_VALUE=1 in smt.state
* Fri Jul 16 2021 Than Ngo <than@redhat.com> - 1.3.8-7 * Tue Feb 08 2022 Than Ngo <than@redhat.com> - 1.3.9-5
- Related: #1938420, Fix checking HCNID array size at boot time - santize devspec output of a newline if one is present
- fixed invalid hex number (multipath)
* Thu Apr 01 2021 Than Ngo <than@redhat.com> - 1.3.8-6 * Fri Jan 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.9-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Tue Dec 07 2021 Than Ngo <than@redhat.com> - 1.3.9-3
- enable support vnic as backend for HNV interface
- fixed hexdump format
- switch to systemd macros in scriptlets
- marked smt.state as %%ghost
* Fri Jul 23 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.9-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Mon Jul 19 2021 Than Ngo <than@redhat.com> - 1.3.9-1
- Rebase to 1.3.9
* Mon May 31 2021 Than Ngo <than@redhat.com> - 1.3.8-9
- Resolves: #1935658, New lparstat -x option to report the security flavor - Resolves: #1935658, New lparstat -x option to report the security flavor
- Resolves: #1953818, Use od instead xxd - Resolves: #1938420, rebase patch fix_boot-time_bonding_interface_cleanup_and_avoid_use_ifcfg
- Resolves: #1938420, rebase patch fix_boot-time_bonding_interface_cleanup_and_avoid_use_ifcfg - Resolves: #1940358, ppc64_cpu --help does not list --version as an option
- Resolves: #1940358, ppc64_cpu --help does not list --version as an option
- Resolves: #1951068, take care of NUMA topology when removing memory (DLPAR) - Resolves: #1951068, take care of NUMA topology when removing memory (DLPAR)
* Wed Feb 03 2021 Than Ngo <than@redhat.com> - 1.3.8-5 * Mon May 03 2021 Than Ngo <than@redhat.com> - 1.3.8-8
- Resolves: #1924150, Fix boot-time bonding interface cleanup and avoid use ifcfg - Use od instead xxd
* Mon Dec 21 2020 Than Ngo <than@redhat.com> - 1.3.8-4 * Mon Feb 08 2021 Than Ngo <than@redhat.com> - 1.3.8-7
- Resolves: #1909526, additional patches to support Linux Hybrid Network Virtualization - updated hcnmgr manpage
- Resolves: #1909135, move commands that dont depend on perl to core subpackage
* Tue Oct 06 2020 Than Ngo <than@redhat.com> - 1.3.8-3 * Mon Feb 08 2021 Than Ngo <than@redhat.com> - 1.3.8-6
- Resolves: #1868474, ofpathname: Use NVMe controller physical nsid - Fix boot-time bonding interface cleanup and avoid use ifcfg
- Resolves: #1885532, sys_ident: Skip length field from search
* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.8-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Tue Dec 22 2020 Than Ngo <than@redhat.com> - 1.3.8-4
- additional patches to support Linux Hybrid Network Virtualization
- move commands that dont depend on perl to core subpackage
- update hcnmgr patch
- sys_ident: Skip length field from search
- ofpathname: Use NVMe controller physical nsid
* Thu Oct 01 2020 Than Ngo <than@redhat.com> - 1.3.8-3
- add hcnmgr man page
* Thu Oct 01 2020 Than Ngo <than@redhat.com> - 1.3.8-2 * Thu Oct 01 2020 Than Ngo <than@redhat.com> - 1.3.8-2
- Related: #1853297, add missing hcnmgr manpage and Req on which - clean up systemd service
* Thu Oct 01 2020 Than Ngo <than@redhat.com> - 1.3.8-1 * Fri Sep 04 2020 Than Ngo <than@redhat.com> - 1.3.8-1
- Resolves: #1853297, rebase to 1.3.8 - update to 1.3.8
- Resolves: #1802181, SR-IOV - Linux Hybrid Network Virtualization
- Resolves: #1844421, Include vcpustat
* Wed Jun 24 2020 Than Ngo <than@redhat.com> - 1.3.6-11 * Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.7-7
- Resolves: #1847604, ofpathname: failed to boot - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Fri Jun 19 2020 Than Ngo <than@redhat.com> - 1.3.6-10 * Thu Jul 09 2020 Than Ngo <than@redhat.com> - 1.3.7-6
- Resolves: #1848839, update lparstat man page with -E option - Track and expose idle PURR and SPURR ticks
- ofpathname: speed up l2of_scsi()
- ofpathname: failed to boot
- update lparstat man page with -E option
- enable support for ibm,drc-info property
* Fri May 22 2020 Than Ngo <than@redhat.com> - 1.3.6-9 * Sat Mar 28 2020 Than Ngo <than@redhat.com> - 1.3.7-5
- Resolves: #1837751, ofpathname: speed up l2of_scsi() - move drmgr in core to avoid pulling in Perl
* Fri May 15 2020 Than Ngo <than@redhat.com> - 1.3.6-8 * Mon Mar 09 2020 Than Ngo <than@redhat.com> - 1.3.7-4
- Related: #1783285, update the patches V4 - update_flash_nv: fixup null byte command substitution warning
- drmgr: Fix segfault when running 'drmgr -c pmig -h'
* Wed May 13 2020 Than Ngo <than@redhat.com> - 1.3.6-7 * Thu Jan 30 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.7-3
- Resolves: #1783285, Track and expose idle PURR and SPURR ticks - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Wed Mar 25 2020 Than Ngo <than@redhat.com> - 1.3.6-6 * Thu Dec 19 2019 Than Ngo <than@redhat.com> - 1.3.7-2
- Resolves: #1819566 - move drmgr in core to avoid pulling in Perl - add systemd service to set default system SMT mode
- Resolves: #1806870 - ignored null byte in input
- Resolves: #1779197 - enable support for ibm,drc-info property
* Wed Dec 04 2019 Than Ngo <than@redhat.com> - 1.3.6-5 * Wed Dec 18 2019 Than Ngo <than@redhat.com> - 1.3.7-1
- Resolves: #1779257, Safe bootlist update - update to 1.3.7
* Wed Jul 24 2019 Than Ngo <than@redhat.com> - 1.3.6-4 * Fri Jul 26 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.6-3
- Resolves: #1719372 - wrong disk gets booted after installation - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Jun 07 2019 Than Ngo <than@redhat.com> - 1.3.6-3 * Sat Feb 02 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.6-2
- Resolves: #1718254, improve handling of errors from subsidiary scripts - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Wed Jun 05 2019 Than Ngo <than@redhat.com> - 1.3.6-2 * Wed Jan 16 2019 Than Ngo <than@redhat.com> - 1.3.6-1
- Resolves: #1716425, lparstat and update_flash fixes - update to 1.3.6
* Mon Apr 01 2019 Than Ngo <than@redhat.com> - 1.3.6-1 * Fri Nov 30 2018 Than Ngo <than@redhat.com> - 1.3.5-4
- Resolves: #1666618, rebase to 1.3.6 - install missing pseries_platform and update_flash_nv man pages
* Tue Dec 04 2018 Than Ngo <than@redhat.com> - 1.3.5-5 * Thu Nov 29 2018 Than Ngo <than@redhat.com> - 1.3.5-3
- Related: #1655903, add missing man pages - added pseries_platform and update_flash_nv man pages
* Tue Dec 04 2018 Than Ngo <than@redhat.com> - 1.3.5-4 * Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.5-2
- Resolves: #1655903, lsslot -c mem is not displaying any information - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Nov 27 2018 Than Ngo <than@redhat.com> - 1.3.5-3
- Resolves: #1653621, fix to display logical name using bootlist -o option
* Sat Nov 10 2018 Than Ngo <than@redhat.com> - 1.3.5-2
- fix metadate issue detected by rpmdiff
Related: #1608172
* Mon Jun 18 2018 Dan Horák <dan[at]danny.cz> - 1.3.5-1 * Mon Jun 18 2018 Dan Horák <dan[at]danny.cz> - 1.3.5-1
- Rebased to 1.3.5 - Rebased to 1.3.5

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (powerpc-utils-1.3.13.tar.gz) = 81fe5588e7330cb0bac81b7106c9949e364fe0b11cc1739a4074fee54c01c363ed8af05488152c9527c56ba053c11278c6b1a2340b2e088a6f25521965e4fc62