Update to 1.3.13

Resolves: RHEL-24535
This commit is contained in:
Than Ngo 2024-11-20 13:52:41 +01:00
parent dd69abbd9a
commit 7757efa247
19 changed files with 8 additions and 2085 deletions

1
.gitignore vendored
View File

@ -26,3 +26,4 @@ powerpc-utils-1.2.2.tar.gz
/powerpc-utils-1.3.10.tar.gz /powerpc-utils-1.3.10.tar.gz
/powerpc-utils-1.3.11.tar.gz /powerpc-utils-1.3.11.tar.gz
/powerpc-utils-1.3.12.tar.gz /powerpc-utils-1.3.12.tar.gz
/powerpc-utils-1.3.13.tar.gz

View File

@ -1,228 +0,0 @@
commit 2af8c0b9a285e8a6104560d0f482819e56060443
Author: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Date: Thu Jul 18 00:39:24 2024 +0530
lparstat: Fix Idle and busy PURR/SPURR
lparstat -E gives %busy and %idle for actual(PURR based) and normalized
(SPURR based).Idle and busy PURR/SPURR values are not adding upto 100%
in case of dedicated-donate and shared partitions, with the present
formula. Because of this, users might get a false impression of resource
utilisation. This is expected because a core can be in either
idle or busy state out of total of 100(core's shared resource can
either be consumed or be left idle). When lpar is in dedicated-donate
or shared,the purr values are not being counted when the CPU is ceded.
The idle_purr is calculated by taking snapshots of purr values at
every idle entry and idle exit. So, when a CPU is ceded, the calculation
for idle_purr will be wrong as purr is not being counted.
Before Change:
|-----------------------------------------------------------------|
| Dedicated-donate (8 cores) : |
|----------------------|---------------------|--------------------|
| | Actual | Normalized |
| Stress-ng threads |---------------------|--------------------|
| | %busy | %idle | %busy | %idle |
|----------------------|----------|----------|---------|----------|
| 0 threads | 0.02 | 0.05 | 0.02 | 0.05 |
|----------------------|----------|----------|---------|----------|
| 8 threads | 32.64 | 17.37 | 35.25 | 18.77 |
|----------------------|----------|----------|---------|----------|
| 16 threads | 58.61 | 16.42 | 63.29 | 17.74 |
|----------------------|----------|----------|---------|----------|
| 24 threads | 78.14 | 21.86 | 84.39 | 23.61 |
|----------------------|----------|----------|---------|----------|
| 32 threads | 83.60 | 16.40 | 90.30 | 17.71 |
|----------------------|----------|----------|---------|----------|
| 40 threads | 91.90 | 6.94 | 98.31 | 7.46 |
|----------------------|----------|----------|---------|----------|
| 48 threads | 96.08 | 3.92 | 102.79 | 4.21 |
|----------------------|----------|----------|---------|----------|
| 56 threads | 98.42 | 1.57 | 105.31 | 1.69 |
|----------------------|----------|----------|---------|----------|
| 64 threads | 100.00 | 0.00 | 106.00 | 0.00 |
|----------------------|----------|----------|---------|----------|
|-----------------------------------------------------------------|
| Shared Capped (8 VP / 4 EC) : |
|----------------------|---------------------|--------------------|
| | Actual | Normalized |
| Stress-ng threads |---------------------|--------------------|
| | %busy | %idle | %busy | %idle |
|----------------------|----------|----------|---------|----------|
| 0 threads | 0.04 | 0.18 | 0.03 | 0.19 |
|----------------------|----------|----------|---------|----------|
| 8 threads | 35.90 | 14.09 | 38.77 | 15.21 |
|----------------------|----------|----------|---------|----------|
| 16 threads | 35.25 | 14.84 | 38.08 | 16.02 |
|----------------------|----------|----------|---------|----------|
| 24 threads | 40.13 | 9.73 | 42.93 | 10.43 |
|----------------------|----------|----------|---------|----------|
| 32 threads | 44.13 | 5.73 | 47.22 | 6.14 |
|----------------------|----------|----------|---------|----------|
| 40 threads | 46.47 | 3.42 | 50.18 | 3.69 |
|----------------------|----------|----------|---------|----------|
| 48 threads | 48.03 | 1.83 | 51.39 | 1.96 |
|----------------------|----------|----------|---------|----------|
| 56 threads | 49.04 | 0.86 | 52.47 | 0.93 |
|----------------------|----------|----------|---------|----------|
| 64 threads | 49.87 | 0.00 | 53.36 | 0.00 |
|----------------------|----------|----------|---------|----------|
This commit, rather than considering delta_idle_purr for calculation of
idle ticks, takes (delta_tb - delta_purr + delta_idle_purr) as total
ticks for which the CPUs were idle. Here, since delta_idle_purr will
also contain some idle ticks, thats why it is added to the formula.
Since, the output was correct for dedicated capped mode, changes has
been made only for shared and dedicated-donate mode.
Further, no changes has been made for calculation of %busy.
Similar changes has been done for SPURR.
After Change:
|-----------------------------------------------------------------|
| Dedicated-donate (8 cores) : |
|----------------------|---------------------|--------------------|
| | Actual | Normalized |
| Stress-ng threads |---------------------|--------------------|
| | %busy | %idle | %busy | %idle |
|----------------------|----------|----------|---------|----------|
| 0 threads | 0.02 | 99.98 | 0.02 | 100.04 |
|----------------------|----------|----------|---------|----------|
| 8 threads | 35.97 | 64.03 | 38.84 | 61.51 |
|----------------------|----------|----------|---------|----------|
| 16 threads | 58.60 | 41.40 | 63.28 | 37.08 |
|----------------------|----------|----------|---------|----------|
| 24 threads | 78.14 | 21.86 | 84.39 | 23.61 |
|----------------------|----------|----------|---------|----------|
| 32 threads | 83.60 | 16.41 | 90.29 | 17.71 |
|----------------------|----------|----------|---------|----------|
| 40 threads | 92.96 | 7.04 | 100.39 | 7.61 |
|----------------------|----------|----------|---------|----------|
| 48 threads | 96.08 | 3.92 | 103.77 | 4.24 |
|----------------------|----------|----------|---------|----------|
| 56 threads | 98.42 | 1.58 | 105.31 | 1.68 |
|----------------------|----------|----------|---------|----------|
| 64 threads | 100.00 | 0.00 | 107.00 | 0.00 |
|----------------------|----------|----------|---------|----------|
|-----------------------------------------------------------------|
| Shared Capped (8 VP / 4 EC) : |
|----------------------|---------------------|--------------------|
| | Actual | Normalized |
| Stress-ng threads |---------------------|--------------------|
| | %busy | %idle | %busy | %idle |
|----------------------|----------|----------|---------|----------|
| 0 threads | 0.03 | 99.97 | 0.19 | 99.44 |
|----------------------|----------|----------|---------|----------|
| 8 threads | 35.91 | 64.09 | 38.78 | 61.58 |
|----------------------|----------|----------|---------|----------|
| 16 threads | 36.83 | 63.17 | 39.78 | 60.55 |
|----------------------|----------|----------|---------|----------|
| 24 threads | 40.16 | 59.84 | 43.37 | 56.95 |
|----------------------|----------|----------|---------|----------|
| 32 threads | 44.47 | 55.53 | 48.02 | 52.38 |
|----------------------|----------|----------|---------|----------|
| 40 threads | 46.55 | 53.45 | 50.27 | 50.04 |
|----------------------|----------|----------|---------|----------|
| 48 threads | 48.13 | 51.87 | 52.48 | 47.82 |
|----------------------|----------|----------|---------|----------|
| 56 threads | 49.01 | 50.99 | 52.93 | 47.41 |
|----------------------|----------|----------|---------|----------|
| 64 threads | 49.90 | 50.10 | 53.40 | 46.19 |
|----------------------|----------|----------|---------|----------|
Before Change:
%idle = delta_idle_purr / delta_tb * 100
After Change:
%idle = (delta_tb - delta_purr + delta_idle_purr) / delta_tb * 100
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/lparstat.c b/src/lparstat.c
index d2fdb3f..9d9ba1b 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -515,11 +515,17 @@ void get_cpu_idle_purr(struct sysentry *unused_se, char *buf)
{
double delta_tb, delta_purr, delta_idle_purr;
double physc, idle;
+ char *descr;
+ char mode[32];
delta_tb = get_scaled_tb();
delta_purr = get_delta_value("purr");
delta_idle_purr = get_delta_value("idle_purr");
+ get_sysdata("shared_processor_mode", &descr, mode);
+ if (!strcmp(mode, "Dedicated"))
+ get_sysdata("DedDonMode", &descr, mode);
+
/*
* Given that these values are read from different
* sources (purr from lparcfg and idle_purr from sysfs),
@@ -528,10 +534,23 @@ void get_cpu_idle_purr(struct sysentry *unused_se, char *buf)
*/
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;
+ /*
+ * Round down delta_purr to delta_tb if delta_tb - delta_purr
+ * error is under -1%.
+ */
+ if (((delta_tb - delta_purr + delta_idle_purr) / delta_tb * 100) > -1 && ((delta_tb - delta_purr + delta_idle_purr) / delta_tb * 100) < 0)
+ delta_purr = delta_tb;
+
+ if (!strcmp(mode, "Capped")) {
+ /* For dedicated - capped mode */
+ physc = (delta_purr - delta_idle_purr) / delta_tb;
+ idle = (delta_purr / delta_tb) - physc;
+ idle *= 100.00;
+ } else {
+ /* For shared and dedicated - donate mode */
+ idle = (delta_tb - delta_purr + delta_idle_purr) / delta_tb;
+ idle *= 100.00;
+ }
sprintf(buf, "%.2f", idle);
}
@@ -559,14 +578,30 @@ void get_cpu_idle_spurr(struct sysentry *unused_se, char *buf)
double delta_tb, delta_spurr, delta_idle_spurr;
double physc, idle;
double rfreq;
+ char *descr;
+ char mode[32];
delta_tb = get_scaled_tb();
delta_spurr = get_delta_value("spurr");
delta_idle_spurr = get_delta_value("idle_spurr");
- physc = (delta_spurr - delta_idle_spurr) / delta_tb;
- idle = (delta_spurr / delta_tb) - physc;
- idle *= 100.00;
+ get_sysdata("shared_processor_mode", &descr, mode);
+ if (!strcmp(mode, "Dedicated"))
+ get_sysdata("DedDonMode", &descr, mode);
+
+ if (delta_spurr > delta_tb)
+ delta_spurr = delta_tb;
+
+ if (!strcmp(mode, "Capped")) {
+ /* For dedicated - capped mode */
+ physc = (delta_spurr - delta_idle_spurr) / delta_tb;
+ idle = (delta_spurr / delta_tb) - physc;
+ idle *= 100.00;
+ } else {
+ /* For shared and dedicated - donate mode */
+ idle = (delta_tb - delta_spurr + delta_idle_spurr) / delta_tb;
+ idle *= 100.00;
+ }
rfreq = round_off_freq();
idle += ((idle * rfreq) / 100);

View File

@ -1,44 +0,0 @@
diff -up powerpc-utils-1.3.12/src/ppc64_cpu.c.me powerpc-utils-1.3.12/src/ppc64_cpu.c
--- powerpc-utils-1.3.12/src/ppc64_cpu.c.me 2024-11-14 17:00:06.002985884 +0100
+++ powerpc-utils-1.3.12/src/ppc64_cpu.c 2024-11-14 17:03:10.401499208 +0100
@@ -56,6 +56,8 @@
#define DIAGNOSTICS_RUN_MODE 42
#define CPU_OFFLINE -1
+#define SYS_SMT_CONTROL "/sys/devices/system/cpu/smt/control"
+
#ifdef HAVE_LINUX_PERF_EVENT_H
struct cpu_freq {
int offline;
@@ -360,6 +362,20 @@ static int is_dscr_capable(void)
return 0;
}
+/*
+ * Depends on kernel's CONFIG_HOTPLUG_CPU
+ */
+static int set_smt_control(int smt_state)
+{
+ if (set_attribute(SYS_SMT_CONTROL, "%d", smt_state)) {
+ /* Silently ignore kernel not supporting this feature */
+ if (errno != ENODEV)
+ perror(SYS_SMT_CONTROL);
+ return -1;
+ }
+ return 0;
+}
+
static int do_smt(char *state, bool numeric)
{
int rc = 0;
@@ -388,7 +404,9 @@ static int do_smt(char *state, bool nume
return -1;
}
- rc = set_smt_state(smt_state);
+ /* Try using smt/control if failing, fall back to the legacy way */
+ if (set_smt_control(smt_state))
+ rc = set_smt_state(smt_state);
}
return rc;

View File

@ -1,27 +0,0 @@
commit 1dc1ecf7dce7825d352b045c98aa51711b58aaca
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Jun 21 15:39:42 2024 -0700
drmgr: Return from get_node_by_name() if matched DRC index
get_node_by_name() should return dr_node if the DRC name or DRC
index is matched. But the current code returns only if the DRC
name is matched. This patch fixes this issue and returns dr_node
if the index is matched.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/common_pci.c b/src/drmgr/common_pci.c
index c6dcfdf..2e0e5fb 100644
--- a/src/drmgr/common_pci.c
+++ b/src/drmgr/common_pci.c
@@ -969,7 +969,7 @@ get_node_by_name(const char *drc_name, uint32_t node_type)
/* See if the drc index was specified */
drc_index = strtoul(drc_name, NULL, 0);
if (node->drc_index == drc_index)
- continue;
+ break;
for (child = node->children; child; child = child->next) {
if (strcmp(drc_name, child->drc_name) == 0)

View File

@ -1,153 +0,0 @@
commit 3a7e77497d2dcf84b5d6525cdfb6e59dfea7ffbb
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Jun 21 15:40:56 2024 -0700
drmgr: Retrieve dr_connector with the specified DRC index
search_drc_list() provides the search based on the key type such
as DRC_NAME, DRC_TYPE, DRC_INDEX or DRC_POWERDOMAIN. But the
current code has get_drc_by_index() which looks in to the DRC list
passed to this function instead of all DRC lists and is not used
right now.
This patch modifies get_drc_by_index() and the corresponding
changes such that it retrieves dr_connector with the specified DRC
index as does in the case of get_drc_by_name().
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 1d9b7e7..655c9d2 100644
--- a/src/drmgr/common_ofdt.c
+++ b/src/drmgr/common_ofdt.c
@@ -650,23 +650,24 @@ drc_index_to_name(uint32_t index, struct dr_connector *drc_list)
}
/**
- * get_drc_by_name
- * @brief Retrieve a dr_connector with the specified drc_name
+ * search_drc_by_key
+ * @brief Retrieve a dr_connector based on DRC name or DRC index
*
* This routine searches the drc lists for a dr_connector with the
- * specified name starting at the specified directory. If a dr_connector
- * is found the root_dir that the dr_connector was found in is also
- * filled out.
+ * specified name or index starting at the specified directory. If
+ * a dr_connector is found the root_dir that the dr_connector was
+ * found in is also filled out.
*
- * @param drc_name name of the dr_connector to search for
+ * @param key to serach for the dr_connector
* @param drc pointer to a drc to point to the found dr_connector
* @param root_dir pointer to buf to fill in with root directory
* @param start_dir, directory to start searching
+ * @param key_type whether the key is DRC name or DRC index
* @returns 0 on success (drc and root_dir filled in), !0 on failure
*/
int
-get_drc_by_name(char *drc_name, struct dr_connector *drc, char *root_dir,
- char *start_dir)
+search_drc_by_key(void *key, struct dr_connector *drc, char *root_dir,
+ char *start_dir, int key_type)
{
struct dr_connector *drc_list = NULL;
struct dr_connector *drc_entry;
@@ -681,7 +682,7 @@ get_drc_by_name(char *drc_name, struct dr_connector *drc, char *root_dir,
if (drc_list == NULL)
return -1;
- drc_entry = search_drc_list(drc_list, NULL, DRC_NAME, drc_name);
+ drc_entry = search_drc_list(drc_list, NULL, key_type, key);
if (drc_entry != NULL) {
memcpy(drc, drc_entry, sizeof(*drc));
sprintf(root_dir, "%s", start_dir);
@@ -700,7 +701,8 @@ get_drc_by_name(char *drc_name, struct dr_connector *drc, char *root_dir,
continue;
sprintf(dir_path, "%s/%s", start_dir, de->d_name);
- rc = get_drc_by_name(drc_name, drc, root_dir, dir_path);
+ rc = search_drc_by_key(key, drc, root_dir, dir_path,
+ key_type);
if (rc == 0)
break;
}
@@ -709,17 +711,57 @@ get_drc_by_name(char *drc_name, struct dr_connector *drc, char *root_dir,
return rc;
}
-struct dr_connector *
-get_drc_by_index(uint32_t drc_index, struct dr_connector *drc_list)
+/**
+ * get_drc_by_name
+ * @brief Retrieve a dr_connector with the specified drc_name
+ *
+ * This routine searches the drc lists for a dr_connector with the
+ * specified name starting at the specified directory. If a dr_connector
+ * is found the root_dir that the dr_connector was found in is also
+ * filled out.
+ *
+ * @param drc_name name of the dr_connector to search for
+ * @param drc pointer to a drc to point to the found dr_connector
+ * @param root_dir pointer to buf to fill in with root directory
+ * @param start_dir, directory to start searching
+ * @returns 0 on success (drc and root_dir filled in), !0 on failure
+ */
+int
+get_drc_by_name(char *drc_name, struct dr_connector *drc, char *root_dir,
+ char *start_dir)
{
- struct dr_connector *drc;
+ int rc;
- for (drc = drc_list; drc; drc = drc->next) {
- if (drc->index == drc_index)
- return drc;
- }
+ rc = search_drc_by_key(drc_name, drc, root_dir, start_dir, DRC_NAME);
- return NULL;
+ return rc;
+}
+
+/**
+ * get_drc_by_index
+ * @brief Retrieve a dr_connector with the specified index
+ *
+ * This routine searches the drc lists for a dr_connector with the
+ * specified index starting at the specified directory. If a dr_connector
+ * is found the root_dir that the dr_connector was found in is also
+ * filled out.
+ *
+ * @param index of the dr_connector to search for
+ * @param drc pointer to a drc to point to the found dr_connector
+ * @param root_dir pointer to buf to fill in with root directory
+ * @param start_dir, directory to start searching
+ * @returns 0 on success (drc and root_dir filled in), !0 on failure
+ */
+int
+get_drc_by_index(uint32_t index, struct dr_connector *drc, char *root_dir,
+ char *start_dir)
+{
+ int rc;
+
+ rc = search_drc_by_key((void *)&index, drc, root_dir, start_dir,
+ DRC_INDEX);
+
+ return rc;
}
/*
diff --git a/src/drmgr/ofdt.h b/src/drmgr/ofdt.h
index bd90810..6c1b961 100644
--- a/src/drmgr/ofdt.h
+++ b/src/drmgr/ofdt.h
@@ -177,6 +177,7 @@ int get_my_drc_index(char *, uint32_t *);
int drc_name_to_index(const char *, struct dr_connector *);
char * drc_index_to_name(uint32_t, struct dr_connector *);
int get_drc_by_name(char *, struct dr_connector *, char *, char *);
+int get_drc_by_index(uint32_t, struct dr_connector *, char *, char *);
int get_min_common_depth(void);
int get_assoc_arrays(const char *dir, struct assoc_arrays *aa,

View File

@ -1,57 +0,0 @@
commit aa5feef7c7657fb764d732e831c9f7c7b9820498
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Jun 21 15:41:46 2024 -0700
drmgr: Introduce get_my_partner_drc_index()
get_my_partner_drc_index() is called to retrieve DRC index from the
"ibm,multipath-partner-drc" property. This property is available
in the parent device node if the device has miltipath partner device.
"ibm,multipath-partner-drc" has the DRC index of the partner device.
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 655c9d2..1e5fe53 100644
--- a/src/drmgr/common_ofdt.c
+++ b/src/drmgr/common_ofdt.c
@@ -609,6 +609,26 @@ get_my_drc_index(char *of_path, uint32_t *index)
return rc;
}
+/**
+ * get_my_partner_drc_index
+ *
+ * @param of_full_path
+ * @param index
+ * @returns 0 on success, !0 otherwise
+ */
+int get_my_partner_drc_index(struct dr_node *node, uint32_t *index)
+{
+ int rc;
+
+ if (node == NULL)
+ return -1;
+
+ rc = get_ofdt_uint_property(node->ofdt_path,
+ "ibm,multipath-partner-drc", index);
+
+ return rc;
+}
+
/**
* drc_name_to_index
* @brief Find the drc index for the given name
diff --git a/src/drmgr/ofdt.h b/src/drmgr/ofdt.h
index 6c1b961..08d34e1 100644
--- a/src/drmgr/ofdt.h
+++ b/src/drmgr/ofdt.h
@@ -174,6 +174,7 @@ struct dr_connector *search_drc_list(struct dr_connector *,
struct dr_connector *, int, void *);
int get_my_drc_index(char *, uint32_t *);
+int get_my_partner_drc_index(struct dr_node *, uint32_t *);
int drc_name_to_index(const char *, struct dr_connector *);
char * drc_index_to_name(uint32_t, struct dr_connector *);
int get_drc_by_name(char *, struct dr_connector *, char *, char *);

View File

@ -1,70 +0,0 @@
commit 8751abf3cf0eb2733162931a6b38db4431699ebd
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Jun 21 15:42:45 2024 -0700
drmgr/phb: Add multipath partner device support for remove
The PHB node can have "ibm,multipath-partner-drc" property
which means the device can be also configured with multipath
partner path. This property provides the DRC index of the
partner device. For the hotplug removal, both paths should
be removed and the following steps will be executed:
- Find the partner path DRC index from "ibm,multipath-partner-drc"
property for the specified device
- If the partner path is configured, notify user about the
removal of partner path if available. Then the user should issue
issue separate drmgr command to remove the partner path.
- Remove the primary path
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_phb.c b/src/drmgr/drslot_chrp_phb.c
index f59baa4..b3a4190 100644
--- a/src/drmgr/drslot_chrp_phb.c
+++ b/src/drmgr/drslot_chrp_phb.c
@@ -283,9 +283,11 @@ static int disable_os_hp_children(struct dr_node *phb)
*/
static int remove_phb(void)
{
- struct dr_node *phb;
+ struct dr_node *phb, *partner_phb = NULL;
struct dr_node *child;
struct dr_node *hp_list = NULL;
+ uint32_t partner_drc_index = 0;
+ char drc_index_str[10];
int rc = 0;
phb = get_node_by_name(usr_drc_name, PHB_NODES);
@@ -305,6 +307,20 @@ static int remove_phb(void)
goto phb_remove_error;
}
+ /* Find the multipath partner device index if available */
+ rc = get_my_partner_drc_index(phb, &partner_drc_index);
+ if (!rc && partner_drc_index) {
+ sprintf(drc_index_str, "%d", partner_drc_index);
+
+ /* Find the partner phb device */
+ partner_phb = get_node_by_name(drc_index_str, PHB_NODES);
+ if (partner_phb) {
+ printf("Partner adapter location : %s",
+ partner_phb->drc_name);
+ printf(" Partner adapter must be removed\n");
+ }
+ }
+
/* Now, disable any hotplug children */
hp_list = get_hp_nodes();
@@ -358,6 +374,9 @@ phb_remove_error:
if (phb)
free_node(phb);
+ if (partner_phb)
+ free_node(partner_phb);
+
if (hp_list)
free_node(hp_list);

View File

@ -1,84 +0,0 @@
commit fe0c826464620fde9124f903d97102bb4237afa7
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Jun 21 15:43:24 2024 -0700
drmgr/phb: Add multipath partner device support for hotplug add
The PHB node can have "ibm,multipath-partner-drc" property
which means the device can be also configured with multipath
partner path. This property provides the DRC index of the
partner device. So for the hotplug add, both paths should be
added and the following steps will be executed for the PHB add:
- Add the specified PHB device
- Find the partner path DRC index from "ibm,multipath-partner-drc"
property for the specified device
- If the node has this property and the partner path is
already added, notify user about the partner device.
- If the node has this property and the partner path can be
configured, notify user to configure and add the partner
device.
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_phb.c b/src/drmgr/drslot_chrp_phb.c
index b3a4190..220d844 100644
--- a/src/drmgr/drslot_chrp_phb.c
+++ b/src/drmgr/drslot_chrp_phb.c
@@ -441,8 +441,13 @@ static int acquire_phb(char *drc_name, struct dr_node **phb)
*/
static int add_phb(void)
{
- struct dr_node *phb = NULL;
+ struct dr_node *phb = NULL, *partner_phb = NULL;
+ uint32_t partner_drc_index = 0;
+ char drc_index_str[10];
int rc, n_children = 0;
+ struct dr_connector drc;
+ char path[DR_PATH_MAX];
+ int partner_rc = 0;
phb = get_node_by_name(usr_drc_name, PHB_NODES);
if (phb) {
@@ -507,10 +512,40 @@ static int add_phb(void)
}
}
+ if (!rc) {
+ /* Find the multipath partner device index if available */
+ partner_rc = get_my_partner_drc_index(phb, &partner_drc_index);
+ if (!partner_rc && partner_drc_index) {
+ sprintf(drc_index_str, "%d", partner_drc_index);
+ /* If the partner device is already added */
+ partner_phb = get_node_by_name(drc_index_str,
+ PHB_NODES);
+ if (partner_phb) {
+ printf("<%s> has partner device <%s>\n",
+ phb->drc_name, partner_phb->drc_name);
+ } else {
+ /*
+ * Find out if the partner device can be
+ * configured. Get the DRC info for the
+ * partner DRC index
+ */
+ partner_rc = get_drc_by_index(partner_drc_index,
+ &drc, path, OFDT_BASE);
+ if (partner_rc)
+ printf("<%s> can have partner "
+ "device but not assigned to "
+ "LPAR yet\n", phb->drc_name);
+ }
+ }
+ }
+
phb_add_error:
if (phb)
free_node(phb);
+ if (partner_phb)
+ free_node(partner_phb);
+
return rc;
}

View File

@ -1,334 +0,0 @@
commit 1f8b5ef8092a8466bdcb29604939ae7193b79ba0
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Jun 21 15:44:36 2024 -0700
drmgr/pci: Add multipath partner device support for hotplug remove
If the PCI device has multipath partner device, its device node
contains "ibm,multipath-partner-drc" property which gives the
DRC index of the partner device. For the hotplug removal, if
the partner path is also configured, both paths must be
removed before instructing the user to remove the device from
identified slot.
So the following steps will be executed for the removal:
- Find the partner path DRC index from "ibm,multipath-partner-drc"
property
- Remove the primary path
- Remove the partner path if it is configured.
- Notify user to remove PCI card from the specified slot.
Since both paths will be using the same slot, LED indicators and
the slot identification will be done only for the primary device.
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 f2b76ef..87edf67 100644
--- a/src/drmgr/drslot_chrp_pci.c
+++ b/src/drmgr/drslot_chrp_pci.c
@@ -26,6 +26,7 @@
#include <errno.h>
#include <locale.h>
#include <librtas.h>
+#include <stdbool.h>
#include "rtas_calls.h"
#include "dr.h"
@@ -99,9 +100,9 @@ identify_slot(struct dr_node *node)
if (process_led(node, LED_ID))
return USER_QUIT;
- printf("The visual indicator for the specified PCI slot has\n"
- "been set to the identify state. Press Enter to continue\n"
- "or enter x to exit.\n");
+ printf("The visual indicator for the PCI slot <%s>\n"
+ "has been set to the identify state. Press Enter to\n"
+ "continue or enter x to exit.\n", node->drc_name);
if (getchar() == '\n')
return (USER_CONT);
@@ -146,7 +147,8 @@ find_drc_name(uint32_t drc_index, struct dr_node *all_nodes)
* @returns pointer to slot on success, NULL otherwise
*/
static struct dr_node *
-find_slot(char *drc_name, struct dr_node *all_nodes)
+find_slot(char *drc_name, uint32_t drc_index,
+ struct dr_node *all_nodes, bool partner)
{
struct dr_node *node; /* working pointer */
@@ -157,11 +159,17 @@ find_slot(char *drc_name, struct dr_node *all_nodes)
while (node != NULL) {
if (cmp_drcname(node->drc_name, drc_name))
break;
+ else if (drc_index && (node->drc_index == drc_index))
+ break;
else
node = node->next;
}
- if ((node == NULL) || (node->skip))
+ /*
+ * Partner path may not be assigned to LPAR.
+ * So ignore if can not find the node for the partner.
+ */
+ if ((!partner && (node == NULL)) || (node && (node->skip)))
say(ERROR, "The specified PCI slot is either invalid\n"
"or does not support hot plug operations.\n");
@@ -316,7 +324,7 @@ static int do_identify(struct dr_node *all_nodes)
int usr_key;
int led_state;
- node = find_slot(usr_drc_name, all_nodes);
+ node = find_slot(usr_drc_name, 0, all_nodes, 0);
if (node == NULL)
return -1;
@@ -509,6 +517,32 @@ static int do_insert_card_work(struct dr_node *node)
return 0;
}
+/**
+ * find_partner_node
+ *
+ * Find the partner DRC index and retrieve the partner node.
+ */
+static struct dr_node *
+find_partner_node(struct dr_node *node, struct dr_node *all_nodes)
+{
+ struct dr_node *partner_node = NULL;
+ uint32_t partner_index = 0;
+ int rc;
+
+ /*
+ * Expect the partner device only for the PCI node
+ */
+ if (!node->children)
+ return NULL;
+
+ /* Find the multipath partner device index if available */
+ rc = get_my_partner_drc_index(node->children, &partner_index);
+ if (!rc)
+ partner_node = find_slot(NULL, partner_index, all_nodes, 1);
+
+ return partner_node;
+}
+
/**
* do_add
*
@@ -530,7 +564,7 @@ static int do_add(struct dr_node *all_nodes)
int usr_key = USER_CONT;
int rc;
- node = find_slot(usr_drc_name, all_nodes);
+ node = find_slot(usr_drc_name, 0, all_nodes, 0);
if (node == NULL)
return -1;
@@ -602,50 +636,50 @@ static int do_add(struct dr_node *all_nodes)
* Open Firmware device tree. The slot is isolated and powered off,
* and the LED is turned off.
*
- * @returns pointer slot on success, NULL on failure
+ * @returns 0 on success, -1 on failure
*/
-static struct dr_node *remove_work(struct dr_node *all_nodes)
+static int remove_work(struct dr_node *node, bool partner_device)
{
- struct dr_node *node;
struct dr_node *child;
int rc;
int usr_key = USER_CONT;
- node = find_slot(usr_drc_name, all_nodes);
if (node == NULL)
- return NULL;
+ return -1;
say(DEBUG, "found node: drc name=%s, index=0x%x, path=%s\n",
node->drc_name, node->drc_index, node->ofdt_path);
if (is_display_adapter(node)) {
say(ERROR, "DLPAR of display adapters is not supported.\n");
- return NULL;
+ return -1;
}
- if (usr_prompt) {
- if (usr_slot_identification)
- usr_key = identify_slot(node);
+ if (!partner_device) {
+ if (usr_prompt) {
+ if (usr_slot_identification)
+ usr_key = identify_slot(node);
- if (usr_key == USER_QUIT) {
- if (node->children == NULL)
- process_led(node, LED_OFF);
- else
- process_led(node, LED_ON);
- return NULL;
+ if (usr_key == USER_QUIT) {
+ if (node->children == NULL)
+ process_led(node, LED_OFF);
+ else
+ process_led(node, LED_ON);
+ return -1;
+ }
}
- }
- /* Turn on the LED while we go do some work. */
- if (process_led(node, LED_ON))
- return NULL;
+ /* Turn on the LED while we go do some work. */
+ if (process_led(node, LED_ON))
+ return -1;
- /* Make sure there's something there to remove. */
- if (node->children == NULL) {
- process_led(node, LED_OFF);
- say(ERROR, "There is no configured card to remove from the "
- "specified PCI slot.\n");
- return NULL;
+ /* Make sure there's something there to remove. */
+ if (node->children == NULL) {
+ process_led(node, LED_OFF);
+ say(ERROR, "There is no configured card to remove "
+ "from the specified PCI slot.\n");
+ return -1;
+ }
}
if (!pci_virtio) {
@@ -660,7 +694,7 @@ static struct dr_node *remove_work(struct dr_node *all_nodes)
int rc = get_hp_adapter_status(node->drc_name);
if (rc != NOT_CONFIG) {
say(ERROR, "Unconfig adapter failed.\n");
- return NULL;
+ return -1;
}
} else {
/* In certain cases such as a complete failure of the
@@ -697,12 +731,12 @@ static struct dr_node *remove_work(struct dr_node *all_nodes)
rtas_set_indicator(ISOLATION_STATE, node->drc_index,
ISOLATE);
set_power(node->drc_power, POWER_OFF);
- return NULL;
+ return -1;
}
}
if (pci_hotplug_only)
- return node;
+ return 0;
/* We have to isolate and power off before
* allowing the user to physically remove
@@ -719,7 +753,7 @@ static struct dr_node *remove_work(struct dr_node *all_nodes)
say(ERROR, "%s", sw_error);
set_power(node->drc_power, POWER_OFF);
- return NULL;
+ return rc;
}
say(DEBUG, "is calling set_power(POWER_OFF index 0x%x, power_domain "
@@ -733,10 +767,10 @@ static struct dr_node *remove_work(struct dr_node *all_nodes)
say(ERROR, "%s", sw_error);
set_power(node->drc_power, POWER_OFF);
- return NULL;
+ return rc;
}
- return node;
+ return 0;
}
/**
@@ -759,13 +793,27 @@ static struct dr_node *remove_work(struct dr_node *all_nodes)
*/
static int do_remove(struct dr_node *all_nodes)
{
- struct dr_node *node;
+ struct dr_node *node, *partner_node = NULL;
- /* Remove the specified slot and update the device-tree */
- node = remove_work(all_nodes);
+ node = find_slot(usr_drc_name, 0, all_nodes, 0);
if (node == NULL)
return -1;
+ partner_node = find_partner_node(node, all_nodes);
+ if (partner_node)
+ printf("<%s> and <%s> are\nmultipath partner devices. "
+ "So <%s> will\nbe also removed.\n", node->drc_name,
+ partner_node->drc_name, partner_node->drc_name);
+
+ /* Remove the specified slot and update the device-tree */
+ if (remove_work(node, false))
+ return -1;
+
+ if (partner_node) {
+ if (remove_work(partner_node, true))
+ return -1;
+ }
+
/* Prompt user to remove card and to press
* Enter to continue. Can't exit out of here.
*/
@@ -773,10 +821,10 @@ static int do_remove(struct dr_node *all_nodes)
if (process_led(node, LED_ACTION))
return -1;
- printf("The visual indicator for the specified PCI slot "
- "has\nbeen set to the action state. Remove the PCI "
- "card\nfrom the identified slot and press Enter to "
- "continue.\n");
+ printf("The visual indicator for the specified PCI "
+ "slot has\nbeen set to the action state. "
+ "Remove the PCI card\nfrom the identified "
+ "slot and press Enter to continue.\n");
getchar();
if (process_led(node, LED_OFF))
return -1;
@@ -810,11 +858,14 @@ static int do_replace(struct dr_node *all_nodes)
struct dr_node *repl_node;
int rc;
+ repl_node = find_slot(usr_drc_name, 0, all_nodes, 0);
+ if (repl_node == NULL)
+ return -1;
+
/* Call the routine which does the work of getting the node info,
* then removing it from the OF device tree.
*/
- repl_node = remove_work(all_nodes);
- if (repl_node == NULL)
+ if (remove_work(repl_node, false))
return -1;
if (!repl_node->children) {
@@ -856,12 +907,16 @@ static int do_replace(struct dr_node *all_nodes)
if (repl_node->post_replace_processing) {
int prompt_save = usr_prompt;
+ struct dr_node *node = repl_node;
say(DEBUG, "Doing post replacement processing...\n");
/* disable prompting for post-processing */
usr_prompt = 0;;
- repl_node = remove_work(repl_node);
+ repl_node = find_slot(usr_drc_name, 0, node, 0);
+ if (remove_work(repl_node, false))
+ return -1;
+
rc = add_work(repl_node);
if (!rc)
set_hp_adapter_status(PHP_CONFIG_ADAPTER,

View File

@ -1,304 +0,0 @@
commit 4e6670df0da2b92a33dd880ce987823358f298bf
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Jun 21 15:45:20 2024 -0700
drmgr/pci: Add multipath partner device support for hotplug add
If the PCI device has multipath partner device, the firmware
provides partner DRC index in "ibm,multipath-partner-drc"
property and this property is available in the PCI device node.
So when the PCI device add is initiated, both paths will be
added if the partner path is also configured and enabled with
the following steps:
- Identify slot and notify user to add the device
- Add the path and enable for the specified device
- Find the partner path DRC index from "ibm,multipath-partner-drc"
property for the specified device
- Add the partner path if it is also configured
- Notify user about adding partner path
Since both paths will be using the same slot, LED indicators and
the slot identification will be done only for the primary device.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/common_pci.c b/src/drmgr/common_pci.c
index 2e0e5fb..2411641 100644
--- a/src/drmgr/common_pci.c
+++ b/src/drmgr/common_pci.c
@@ -295,7 +295,7 @@ add_child_node(struct dr_node *parent, char *child_path)
* @param node
* @returns 0 on success, !0 otherwise
*/
-static int
+int
init_node(struct dr_node *node)
{
DIR *d;
diff --git a/src/drmgr/drslot_chrp_pci.c b/src/drmgr/drslot_chrp_pci.c
index 87edf67..2b8579b 100644
--- a/src/drmgr/drslot_chrp_pci.c
+++ b/src/drmgr/drslot_chrp_pci.c
@@ -31,6 +31,7 @@
#include "rtas_calls.h"
#include "dr.h"
#include "drpci.h"
+#include "ofdt.h"
static char *sw_error = "Internal software error. Contact your service "
"representative.\n";
@@ -367,27 +368,38 @@ static int do_identify(struct dr_node *all_nodes)
* off, isolated, and the LED is turned off.
*
* @param slot
+ * @param partner path or not
* @returns 0 on success, !0 on failure
*/
-static int add_work(struct dr_node *node)
+static int add_work(struct dr_node *node, bool partner_device)
{
- int pow_state; /* Tells us if power was turned on when */
- int iso_state; /* Tells us isolation state after */
+ int pow_state = POWER_OFF; /* Tells us if power was turned */
+ /* on when */
+ int iso_state = ISOLATE; /* Tells us isolation state after */
int rc;
struct of_node *new_nodes;/* nodes returned from configure_connector */
- /* if we're continuing, set LED_ON and see if a card is really there. */
- if (process_led(node, LED_ON))
- return -1;
+ /*
+ * Already checked the card presence for the original device
+ * and both multipaths use the same card. So do not need to
+ * check the card presence again for the partner device.
+ */
+ if (!partner_device) {
+ /* if we're continuing, set LED_ON and see if a card */
+ /* is really there. */
+ if (process_led(node, LED_ON))
+ return -1;
- say(DEBUG, "is calling card_present\n");
- rc = card_present(node, &pow_state, &iso_state);
- if (!rc) {
- say(ERROR, "No PCI card was detected in the specified "
- "PCI slot.\n");
- rtas_set_indicator(ISOLATION_STATE, node->drc_index, ISOLATE);
- set_power(node->drc_power, POWER_OFF);
- return -1;
+ say(DEBUG, "is calling card_present\n");
+ rc = card_present(node, &pow_state, &iso_state);
+ if (!rc) {
+ say(ERROR, "No PCI card was detected in the specified "
+ "PCI slot.\n");
+ rtas_set_indicator(ISOLATION_STATE, node->drc_index,
+ ISOLATE);
+ set_power(node->drc_power, POWER_OFF);
+ return -1;
+ }
}
if (!pow_state) {
@@ -461,7 +473,7 @@ static int add_work(struct dr_node *node)
* power to a slot off. The prompts the user to insert the new card
* into the slot.
*/
-static int do_insert_card_work(struct dr_node *node)
+static int do_insert_card_work(struct dr_node *node, bool partner_device)
{
int rc;
@@ -495,18 +507,18 @@ static int do_insert_card_work(struct dr_node *node)
return -1;
}
- if (usr_prompt) {
+ if (usr_prompt && !partner_device) {
/* Prompt user to put in card and to press
* Enter to continue or other key to exit.
*/
if (process_led(node, LED_ACTION))
return -1;
- printf("The visual indicator for the specified PCI slot has\n"
- "been set to the action state. Insert the PCI card\n"
- "into the identified slot, connect any devices to be\n"
- "configured and press Enter to continue. Enter x to "
- "exit.\n");
+ printf("The visual indicator for the PCI slot <%s>\n"
+ "has been set to the action state. Insert the PCI\n"
+ "card into the identified slot, connect any devices\n"
+ "to be configured and press Enter to continue.\n"
+ "Enter x to exit.\n", node->drc_name);
if (!(getchar() == '\n')) {
process_led(node, LED_OFF);
@@ -543,6 +555,58 @@ find_partner_node(struct dr_node *node, struct dr_node *all_nodes)
return partner_node;
}
+static int insert_add_work(struct dr_node *node, bool partner_device)
+{
+ int usr_key = USER_CONT;
+ int rc;
+
+ if (!partner_device) {
+ /* Prompt user only if in interactive mode. */
+ if (usr_prompt) {
+ if (usr_slot_identification)
+ usr_key = identify_slot(node);
+
+ if (usr_key == USER_QUIT) {
+ if (node->children == NULL)
+ process_led(node, LED_OFF);
+ else
+ process_led(node, LED_ON);
+ return 0;
+ }
+ }
+
+ if (node->children != NULL) {
+ /* If there's already something here, turn the
+ * LED on and exit with user error.
+ */
+ process_led(node, LED_ON);
+ say(ERROR, "The specified PCI slot is already occupied.\n");
+ return -1;
+ }
+ }
+
+ if (!pci_hotplug_only) {
+ rc = do_insert_card_work(node, partner_device);
+ if (rc)
+ return rc;
+ }
+
+ /* Call the routine which determines
+ * what the user wants and does it.
+ */
+ rc = add_work(node, partner_device);
+ if (rc)
+ return rc;
+
+ /*
+ * Need to populate w/ children to retrieve partner device
+ */
+ if (init_node(node))
+ return -1;
+
+ return 1;
+}
+
/**
* do_add
*
@@ -560,8 +624,7 @@ find_partner_node(struct dr_node *node, struct dr_node *all_nodes)
*/
static int do_add(struct dr_node *all_nodes)
{
- struct dr_node *node;
- int usr_key = USER_CONT;
+ struct dr_node *node, *partner_node = NULL;
int rc;
node = find_slot(usr_drc_name, 0, all_nodes, 0);
@@ -573,51 +636,32 @@ static int do_add(struct dr_node *all_nodes)
return -1;
}
- /* Prompt user only if in interactive mode. */
- if (usr_prompt) {
- if (usr_slot_identification)
- usr_key = identify_slot(node);
-
- if (usr_key == USER_QUIT) {
- if (node->children == NULL)
- process_led(node, LED_OFF);
- else
- process_led(node, LED_ON);
- return 0;
- }
- }
-
- if (node->children != NULL) {
- /* If there's already something here, turn the
- * LED on and exit with user error.
- */
- process_led(node, LED_ON);
- say(ERROR, "The specified PCI slot is already occupied.\n");
- return -1;
- }
+ rc = insert_add_work(node, false);
+ if (rc <= 0)
+ return rc;
- if (!pci_hotplug_only) {
- rc = do_insert_card_work(node);
- if (rc)
+ partner_node = find_partner_node(node, all_nodes);
+ if (partner_node) {
+ printf("<%s> and <%s> are\nmultipath partner devices. "
+ "So <%s> is\nalso added.\n", node->drc_name,
+ partner_node->drc_name, partner_node->drc_name);
+ rc = insert_add_work(partner_node, true);
+ if (rc <= 0)
return rc;
}
- /* Call the routine which determines
- * what the user wants and does it.
- */
- rc = add_work(node);
- if (rc)
- return rc;
-
say(DEBUG, "is calling enable_slot to config adapter\n");
/* Try to config the adapter. The rpaphp module doesn't play well with
* qemu pci slots so we let the generic kernel pci code probe the device
* by rescanning the bus in the qemu virtio case.
*/
- if (!pci_virtio)
+ if (!pci_virtio) {
set_hp_adapter_status(PHP_CONFIG_ADAPTER, node->drc_name);
- else
+ if (partner_node)
+ set_hp_adapter_status(PHP_CONFIG_ADAPTER,
+ partner_node->drc_name);
+ } else
pci_rescan_bus();
return 0;
@@ -896,7 +940,7 @@ static int do_replace(struct dr_node *all_nodes)
}
}
- rc = add_work(repl_node);
+ rc = add_work(repl_node, false);
if (rc)
return rc;
@@ -917,7 +961,7 @@ static int do_replace(struct dr_node *all_nodes)
if (remove_work(repl_node, false))
return -1;
- rc = add_work(repl_node);
+ rc = add_work(repl_node, false);
if (!rc)
set_hp_adapter_status(PHP_CONFIG_ADAPTER,
repl_node->drc_name);
diff --git a/src/drmgr/ofdt.h b/src/drmgr/ofdt.h
index 08d34e1..e9ebd03 100644
--- a/src/drmgr/ofdt.h
+++ b/src/drmgr/ofdt.h
@@ -184,6 +184,7 @@ int get_min_common_depth(void);
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 *);
static inline int aa_index_to_node(struct assoc_arrays *aa, uint32_t aa_index)
{

View File

@ -1,173 +0,0 @@
commit f40a63b15c5639df93405b925a4dde740d9bfa23
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Jun 21 15:45:58 2024 -0700
drmgr/pci: Add multipath partner device support for hotplug replace
If the PCI device has multipath partner device, its device node
contains "ibm,multipath-partner-drc" property which gives the DRC
index of the partner device.
So for the replace operation, the following steps will be executed:
- Find the device based on the partner DRC index of the requested
device
- Remove the requested device
- Remove the partner path
- Add the new device based on user input
- Find the device based on the partner DRC index of the new device
- Add the partner path of the new device
Since both paths will be using the same slot, LED indicators and
the slot identification will be done only for the primary device
in both removal and add operations.
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 2b8579b..ac078db 100644
--- a/src/drmgr/drslot_chrp_pci.c
+++ b/src/drmgr/drslot_chrp_pci.c
@@ -877,6 +877,44 @@ static int do_remove(struct dr_node *all_nodes)
return 0;
}
+static int replace_add_work(struct dr_node *node, bool partner_device)
+{
+
+ say(DEBUG, "repl_node:path=%s node:path=%s\n",
+ node->ofdt_path, node->children->ofdt_path);
+
+ /* Prompt user to replace card and to press
+ * Enter to continue or x to exit. Exiting here
+ * means the original card has been removed.
+ */
+ if (usr_prompt && !partner_device) {
+ if (process_led(node, LED_ACTION))
+ return -1;
+
+ printf("The visual indicator for the specified PCI slot <%s>\n"
+ "has been set to the action state. Replace the PCI\n"
+ "card in the identified slot and press Enter to "
+ "continue.\nEnter x to exit. Exiting now leaves the "
+ "PCI slot\nin the removed state.\n",
+ node->drc_name);
+
+ if (!(getchar() == '\n')) {
+ process_led(node, LED_OFF);
+ return 0;
+ }
+ }
+
+ if (add_work(node, partner_device))
+ return -1;
+
+ say(DEBUG, "CONFIGURING the card in node[name=%s, path=%s]\n",
+ node->drc_name, node->ofdt_path);
+
+ set_hp_adapter_status(PHP_CONFIG_ADAPTER, node->drc_name);
+
+ return 1;
+}
+
/**
* do_replace
* @brief Allows the replacement of an adapter connected to a
@@ -899,55 +937,43 @@ static int do_remove(struct dr_node *all_nodes)
*/
static int do_replace(struct dr_node *all_nodes)
{
- struct dr_node *repl_node;
+ struct dr_node *repl_node, *partner_node = NULL;
int rc;
repl_node = find_slot(usr_drc_name, 0, all_nodes, 0);
if (repl_node == NULL)
return -1;
+ partner_node = find_partner_node(repl_node, all_nodes);
+ if (partner_node)
+ printf("<%s> and <%s> are\nmultipath partner devices. "
+ "So <%s> will\nbe also replaced.\n",
+ repl_node->drc_name, partner_node->drc_name,
+ partner_node->drc_name);
+
/* Call the routine which does the work of getting the node info,
* then removing it from the OF device tree.
*/
if (remove_work(repl_node, false))
return -1;
+ if (partner_node) {
+ if (remove_work(partner_node, true))
+ return -1;
+ }
+
if (!repl_node->children) {
say(ERROR, "Bad node struct.\n");
return -1;
}
- say(DEBUG, "repl_node:path=%s node:path=%s\n",
- repl_node->ofdt_path, repl_node->children->ofdt_path);
-
- /* Prompt user to replace card and to press
- * Enter to continue or x to exit. Exiting here
- * means the original card has been removed.
- */
- if (usr_prompt) {
- if (process_led(repl_node, LED_ACTION))
- return -1;
-
- printf("The visual indicator for the specified PCI slot "
- "has\nbeen set to the action state. Replace the PCI "
- "card\nin the identified slot and press Enter to "
- "continue.\nEnter x to exit. Exiting now leaves the "
- "PCI slot\nin the removed state.\n");
-
- if (!(getchar() == '\n')) {
- process_led(repl_node, LED_OFF);
- return 0;
- }
- }
-
- rc = add_work(repl_node, false);
- if (rc)
+ rc = replace_add_work(repl_node, false);
+ if (rc <= 0)
return rc;
- say(DEBUG, "CONFIGURING the card in node[name=%s, path=%s]\n",
- repl_node->drc_name, repl_node->ofdt_path);
-
- set_hp_adapter_status(PHP_CONFIG_ADAPTER, repl_node->drc_name);
+ rc = replace_add_work(partner_node, true);
+ if (rc <= 0)
+ return rc;
if (repl_node->post_replace_processing) {
int prompt_save = usr_prompt;
@@ -961,11 +987,24 @@ static int do_replace(struct dr_node *all_nodes)
if (remove_work(repl_node, false))
return -1;
+ partner_node = find_partner_node(repl_node, node);
+ if (partner_node) {
+ if (remove_work(partner_node, true))
+ return -1;
+ }
+
rc = add_work(repl_node, false);
if (!rc)
set_hp_adapter_status(PHP_CONFIG_ADAPTER,
repl_node->drc_name);
+ if (partner_node) {
+ rc = add_work(partner_node, true);
+ if (!rc)
+ set_hp_adapter_status(PHP_CONFIG_ADAPTER,
+ partner_node->drc_name);
+ }
+
usr_prompt = prompt_save;
}

View File

@ -1,37 +0,0 @@
commit 5db2df531f9c242b13ef6520814c99685144c6d4
Author: Haren Myneni <haren@linux.ibm.com>
Date: Sat Jun 29 14:14:10 2024 -0700
drmgr: Free nodes returned from configure_connector
of_nodes returned from configure_connector should be freed after
updating the device tree and is missing in acquire_hp_resource()
and add_work(). This patch calls free_of_node() in these functions.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/common_pci.c b/src/drmgr/common_pci.c
index 2411641..759589a 100644
--- a/src/drmgr/common_pci.c
+++ b/src/drmgr/common_pci.c
@@ -1434,6 +1434,7 @@ acquire_hp_resource(struct dr_connector *drc, char *of_path)
return -1;
rc = add_device_tree_nodes(of_path, new_nodes);
+ free_of_node(new_nodes);
if (rc) {
say(ERROR, "add nodes failed for 0x%x\n", drc->index);
return rc;
diff --git a/src/drmgr/drslot_chrp_pci.c b/src/drmgr/drslot_chrp_pci.c
index ac078db..ec3c77c 100644
--- a/src/drmgr/drslot_chrp_pci.c
+++ b/src/drmgr/drslot_chrp_pci.c
@@ -454,6 +454,7 @@ static int add_work(struct dr_node *node, bool partner_device)
say(DEBUG, "Adding %s to %s\n", new_nodes->name, node->ofdt_path);
rc = add_device_tree_nodes(node->ofdt_path, new_nodes);
+ free_of_node(new_nodes);
if (rc) {
say(DEBUG, "add_device_tree_nodes failed at %s\n",
node->ofdt_path);

View File

@ -1,183 +0,0 @@
commit 06c9922a774a6c096acbc69664646386c9e185b5
Author: Haren Myneni <haren@linux.ibm.com>
Date: Fri Aug 2 18:39:06 2024 -0700
drmgr/pci: Do not add partner device if exists in the device tree
For PCI hotplug interface, the partner device will be added or
removed if configured with the primary device add / remove.
Whereas for PHB interface, drmgr notifies the user to add / remove
partner device if configured with the primary device. So there is
a possibility of partner PCI node exists in the device tree when
PCI interface for ADD is executed. The current ADD code in
drslot_chrp_pci.c does not check whether the partner device node
is present and may add / enable partner device again which may give
EEH errors.
See the following sequence to get this scenario:
drmgr -r -c phb -s "PHB 1336" --> Remove primary PHB node
drmgr -r -c pci -s "U50EE.001.WZS000E-P3-C24-R2" --> Remove
partner PCI node
drmgr -a -c phb -s "PHB 1336" --> Add primary PHB node
drmgr -a -c pci -s "U50EE.001.WZS000E-P3-C24-R2" --> Add partner
PCI node and can try to add primary PCI node again. In this case
"U50EE.001.WZS000E-P3-C24-R1".
This patch fixes the issue by checking the device node in the
device tree and add the device if does not present and remove
only if the corresponding device node exists.
Fixes: 4e6670df0da2b92 ("drmgr/pci: Add multipath partner device support for hotplug add")
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
[tyreld: fixed up white space and replace/remove phrasing]
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 ec3c77c..7a52085 100644
--- a/src/drmgr/drslot_chrp_pci.c
+++ b/src/drmgr/drslot_chrp_pci.c
@@ -536,12 +536,15 @@ static int do_insert_card_work(struct dr_node *node, bool partner_device)
* Find the partner DRC index and retrieve the partner node.
*/
static struct dr_node *
-find_partner_node(struct dr_node *node, struct dr_node *all_nodes)
+find_partner_node(struct dr_node *node, struct dr_node *all_nodes,
+ int *dt_entry_present)
{
struct dr_node *partner_node = NULL;
uint32_t partner_index = 0;
int rc;
+ *dt_entry_present = 0;
+
/*
* Expect the partner device only for the PCI node
*/
@@ -550,8 +553,20 @@ find_partner_node(struct dr_node *node, struct dr_node *all_nodes)
/* Find the multipath partner device index if available */
rc = get_my_partner_drc_index(node->children, &partner_index);
- if (!rc)
+ if (!rc) {
partner_node = find_slot(NULL, partner_index, all_nodes, 1);
+ /*
+ * Do not add if the partner entry is already present.
+ * Nothing to remove if the partner node does not exists.
+ */
+ if (partner_node && partner_node->children) {
+ uint32_t index;
+ rc = get_my_drc_index(partner_node->children->ofdt_path,
+ &index);
+ if (!rc && (partner_index == index))
+ *dt_entry_present = 1;
+ }
+ }
return partner_node;
}
@@ -626,6 +641,7 @@ static int insert_add_work(struct dr_node *node, bool partner_device)
static int do_add(struct dr_node *all_nodes)
{
struct dr_node *node, *partner_node = NULL;
+ int dt_entry;
int rc;
node = find_slot(usr_drc_name, 0, all_nodes, 0);
@@ -641,8 +657,8 @@ static int do_add(struct dr_node *all_nodes)
if (rc <= 0)
return rc;
- partner_node = find_partner_node(node, all_nodes);
- if (partner_node) {
+ partner_node = find_partner_node(node, all_nodes, &dt_entry);
+ if (partner_node && !dt_entry) {
printf("<%s> and <%s> are\nmultipath partner devices. "
"So <%s> is\nalso added.\n", node->drc_name,
partner_node->drc_name, partner_node->drc_name);
@@ -839,16 +855,25 @@ static int remove_work(struct dr_node *node, bool partner_device)
static int do_remove(struct dr_node *all_nodes)
{
struct dr_node *node, *partner_node = NULL;
+ int dt_entry;
node = find_slot(usr_drc_name, 0, all_nodes, 0);
if (node == NULL)
return -1;
- partner_node = find_partner_node(node, all_nodes);
- if (partner_node)
- printf("<%s> and <%s> are\nmultipath partner devices. "
- "So <%s> will\nbe also removed.\n", node->drc_name,
- partner_node->drc_name, partner_node->drc_name);
+ partner_node = find_partner_node(node, all_nodes, &dt_entry);
+ if (partner_node) {
+ /*
+ * Remove partner device if exists in the device tree.
+ */
+ if (dt_entry)
+ printf("<%s> and <%s> are\nmultipath partner devices. "
+ "So <%s> will\nalso be removed.\n",
+ node->drc_name, partner_node->drc_name,
+ partner_node->drc_name);
+ else
+ partner_node = NULL;
+ }
/* Remove the specified slot and update the device-tree */
if (remove_work(node, false))
@@ -939,18 +964,23 @@ static int replace_add_work(struct dr_node *node, bool partner_device)
static int do_replace(struct dr_node *all_nodes)
{
struct dr_node *repl_node, *partner_node = NULL;
+ int dt_entry;
int rc;
repl_node = find_slot(usr_drc_name, 0, all_nodes, 0);
if (repl_node == NULL)
return -1;
- partner_node = find_partner_node(repl_node, all_nodes);
- if (partner_node)
- printf("<%s> and <%s> are\nmultipath partner devices. "
- "So <%s> will\nbe also replaced.\n",
- repl_node->drc_name, partner_node->drc_name,
- partner_node->drc_name);
+ partner_node = find_partner_node(repl_node, all_nodes, &dt_entry);
+ if (partner_node) {
+ if (dt_entry)
+ printf("<%s> and <%s> are\nmultipath partner devices. "
+ "So <%s> will\nalso be replaced.\n",
+ repl_node->drc_name, partner_node->drc_name,
+ partner_node->drc_name);
+ else
+ partner_node = NULL;
+ }
/* Call the routine which does the work of getting the node info,
* then removing it from the OF device tree.
@@ -972,9 +1002,11 @@ static int do_replace(struct dr_node *all_nodes)
if (rc <= 0)
return rc;
- rc = replace_add_work(partner_node, true);
- if (rc <= 0)
- return rc;
+ if (partner_node) {
+ rc = replace_add_work(partner_node, true);
+ if (rc <= 0)
+ return rc;
+ }
if (repl_node->post_replace_processing) {
int prompt_save = usr_prompt;
@@ -988,8 +1020,8 @@ static int do_replace(struct dr_node *all_nodes)
if (remove_work(repl_node, false))
return -1;
- partner_node = find_partner_node(repl_node, node);
- if (partner_node) {
+ partner_node = find_partner_node(repl_node, node, &dt_entry);
+ if (partner_node && dt_entry) {
if (remove_work(partner_node, true))
return -1;
}

View File

@ -1,92 +0,0 @@
commit 9ea191d15f4b279923a4c83a94b83436c79e3482
Author: Haren Myneni <haren@linux.ibm.com>
Date: Tue Aug 13 14:40:23 2024 -0700
drmgr/pci: Enable in-kernel functionality to update device tree
drmgr updates the device tree by writing to /proc/ppc64/ofdt. Also
invokes configure_connector RTAS call to retrieve new device nodes
for IO ADD. But this functionality need /dev/mem access which is
restricted under system lockdown.
The kernel updates provided a sysfs file (/sys/kernel/dlpar) that
will allow drmgr command invoke the following interfaces to update
the device tree.
dt add index <DRC index> ---> To add new device nodes to the device
tree which is used for IO ADD.
dt remove index <DRC index> ---> To remove device nodes for IO
REMOVE
This patch checks the kernel interface for the availability of
device tree update feature and adds do_dt_kernel_dlpar() to invoke
the above kernel interfaces.
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 bfec0b9..70f4dfd 100644
--- a/src/drmgr/common.c
+++ b/src/drmgr/common.c
@@ -1504,6 +1504,12 @@ int kernel_dlpar_exists(void)
if (strstr(buf, "cpu"))
return 1;
break;
+ case DRC_TYPE_PCI:
+ case DRC_TYPE_PHB:
+ case DRC_TYPE_SLOT:
+ if (strstr(buf, "dt"))
+ return 1;
+ break;
default:
return 0;
}
diff --git a/src/drmgr/common_pci.c b/src/drmgr/common_pci.c
index 759589a..109e0d2 100644
--- a/src/drmgr/common_pci.c
+++ b/src/drmgr/common_pci.c
@@ -1619,3 +1619,32 @@ int disable_hp_children(char *drc_name)
}
return 0;
}
+
+/*
+ * kernel interface to update device tree nodes.
+ * dlpar dt [add|remove] index <#drc index>
+ */
+int do_dt_kernel_dlpar(uint32_t index, int action)
+{
+ char cmdbuf[256];
+ int offset;
+
+ offset = sprintf(cmdbuf, "%s ", "dt");
+
+ switch (action) {
+ case ADD:
+ offset += sprintf(cmdbuf + offset, "add ");
+ break;
+ case REMOVE:
+ offset += sprintf(cmdbuf + offset, "remove ");
+ break;
+ default:
+ /* Should not happen */
+ say(ERROR, "Invalid action type specified\n");
+ return -EINVAL;
+ }
+
+ offset += sprintf(cmdbuf + offset, "index 0x%x", index);
+
+ return do_kernel_dlpar(cmdbuf, offset);
+}
diff --git a/src/drmgr/dr.h b/src/drmgr/dr.h
index 60c31c4..72ede55 100644
--- a/src/drmgr/dr.h
+++ b/src/drmgr/dr.h
@@ -188,4 +188,5 @@ static inline int do_kernel_dlpar(const char *cmd, int len)
{
return do_kernel_dlpar_common(cmd, len, 0);
}
+int do_dt_kernel_dlpar(uint32_t, int);
#endif

View File

@ -1,136 +0,0 @@
commit 9aaa1a625da9de1ca758c4eb8442589b46927acb
Author: Haren Myneni <haren@linux.ibm.com>
Date: Tue Aug 13 14:40:24 2024 -0700
drmgr/phb: Add kernel interface support for device tree update
Use the following kernel interfaces for PHB device type to update
the device tree if this feature is enabled in the kernel.
dt add index <DRC index> --> for IO add
dt remove index <DRC index> --> for IO remove
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/common_pci.c b/src/drmgr/common_pci.c
index 109e0d2..683d72d 100644
--- a/src/drmgr/common_pci.c
+++ b/src/drmgr/common_pci.c
@@ -1390,7 +1390,6 @@ print_node_list(struct dr_node *first_node)
static int
acquire_hp_resource(struct dr_connector *drc, char *of_path)
{
- struct of_node *new_nodes;
int state;
int rc;
@@ -1429,12 +1428,21 @@ acquire_hp_resource(struct dr_connector *drc, char *of_path)
}
if (state == PRESENT) {
- new_nodes = configure_connector(drc->index);
- if (new_nodes == NULL)
- return -1;
+ /*
+ * Use kernel DLPAR interface if it is enabled
+ */
+ if (kernel_dlpar_exists()) {
+ rc = do_dt_kernel_dlpar(drc->index, ADD);
+ } else {
+ struct of_node *new_nodes;
+
+ new_nodes = configure_connector(drc->index);
+ if (new_nodes == NULL)
+ return -1;
- rc = add_device_tree_nodes(of_path, new_nodes);
- free_of_node(new_nodes);
+ rc = add_device_tree_nodes(of_path, new_nodes);
+ free_of_node(new_nodes);
+ }
if (rc) {
say(ERROR, "add nodes failed for 0x%x\n", drc->index);
return rc;
@@ -1490,7 +1498,14 @@ release_hp_resource(struct dr_node *node)
{
int rc;
- rc = remove_device_tree_nodes(node->ofdt_path);
+ /*
+ * Use kernel DLPAR interface if it is enabled
+ */
+ if (kernel_dlpar_exists())
+ rc = do_dt_kernel_dlpar(node->drc_index, REMOVE);
+ else
+ rc = remove_device_tree_nodes(node->ofdt_path);
+
if (rc) {
say(ERROR, "failed to remove kernel nodes for index 0x%x\n",
node->drc_index);
diff --git a/src/drmgr/drslot_chrp_phb.c b/src/drmgr/drslot_chrp_phb.c
index 220d844..5bf3030 100644
--- a/src/drmgr/drslot_chrp_phb.c
+++ b/src/drmgr/drslot_chrp_phb.c
@@ -108,17 +108,16 @@ release_phb(struct dr_node *phb)
{
int rc;
- rc = remove_device_tree_nodes(phb->ofdt_path);
- if (rc)
- return rc;
-
- if (phb->phb_ic_ofdt_path[0] != '\0') {
- rc = remove_device_tree_nodes(phb->phb_ic_ofdt_path);
- if (rc)
- return rc;
+ if (kernel_dlpar_exists())
+ rc = do_dt_kernel_dlpar(phb->drc_index, REMOVE);
+ else {
+ rc = remove_device_tree_nodes(phb->ofdt_path);
+ if (!rc && (phb->phb_ic_ofdt_path[0] != '\0'))
+ rc = remove_device_tree_nodes(phb->phb_ic_ofdt_path);
}
- rc = release_drc(phb->drc_index, PHB_DEV);
+ if (!rc)
+ rc = release_drc(phb->drc_index, PHB_DEV);
return rc;
}
@@ -390,7 +389,6 @@ phb_remove_error:
static int acquire_phb(char *drc_name, struct dr_node **phb)
{
struct dr_connector drc;
- struct of_node *of_nodes;
char path[DR_PATH_MAX];
int rc;
@@ -405,14 +403,20 @@ static int acquire_phb(char *drc_name, struct dr_node **phb)
if (rc)
return rc;
- of_nodes = configure_connector(drc.index);
- if (of_nodes == NULL) {
- release_drc(drc.index, PHB_DEV);
- return -1;
- }
+ if (kernel_dlpar_exists()) {
+ rc = do_dt_kernel_dlpar(drc.index, ADD);
+ } else {
+ struct of_node *of_nodes;
- rc = add_device_tree_nodes(path, of_nodes);
- free_of_node(of_nodes);
+ of_nodes = configure_connector(drc.index);
+ if (of_nodes == NULL) {
+ release_drc(drc.index, PHB_DEV);
+ return -1;
+ }
+
+ rc = add_device_tree_nodes(path, of_nodes);
+ free_of_node(of_nodes);
+ }
if (rc) {
say(ERROR, "add_device_tree_nodes failed at %s\n", path);
release_drc(drc.index, PHB_DEV);

View File

@ -1,74 +0,0 @@
commit a2d1b70cbc90ba41f16281c48e973309469f5d02
Author: Haren Myneni <haren@linux.ibm.com>
Date: Tue Aug 13 14:40:25 2024 -0700
drmgr/pci: Add kernel interface support for device tree update
Use the following kernel interfaces for PCI device type to update
the device tree if this feature is enabled in the kernel.
dt add index <DRC index> --> for IO add
dt remove index <DRC index> --> for IO remove
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 7a52085..4c41fcd 100644
--- a/src/drmgr/drslot_chrp_pci.c
+++ b/src/drmgr/drslot_chrp_pci.c
@@ -377,7 +377,6 @@ static int add_work(struct dr_node *node, bool partner_device)
/* on when */
int iso_state = ISOLATE; /* Tells us isolation state after */
int rc;
- struct of_node *new_nodes;/* nodes returned from configure_connector */
/*
* Already checked the card presence for the original device
@@ -445,16 +444,26 @@ static int add_work(struct dr_node *node, bool partner_device)
* the return status requires a message, print it out
* and exit, otherwise, add the nodes to the OF tree.
*/
- new_nodes = configure_connector(node->drc_index);
- if (new_nodes == NULL) {
- rtas_set_indicator(ISOLATION_STATE, node->drc_index, ISOLATE);
- set_power(node->drc_power, POWER_OFF);
- return -1;
+ if (kernel_dlpar_exists()) {
+ rc = do_dt_kernel_dlpar(node->drc_index, ADD);
+ } else {
+ struct of_node *new_nodes; /* nodes returned from */
+ /* configure_connector */
+
+ new_nodes = configure_connector(node->drc_index);
+ if (new_nodes == NULL) {
+ rtas_set_indicator(ISOLATION_STATE, node->drc_index,
+ ISOLATE);
+ set_power(node->drc_power, POWER_OFF);
+ return -1;
+ }
+
+ say(DEBUG, "Adding %s to %s\n", new_nodes->name,
+ node->ofdt_path);
+ rc = add_device_tree_nodes(node->ofdt_path, new_nodes);
+ free_of_node(new_nodes);
}
- say(DEBUG, "Adding %s to %s\n", new_nodes->name, node->ofdt_path);
- rc = add_device_tree_nodes(node->ofdt_path, new_nodes);
- free_of_node(new_nodes);
if (rc) {
say(DEBUG, "add_device_tree_nodes failed at %s\n",
node->ofdt_path);
@@ -786,7 +795,10 @@ static int remove_work(struct dr_node *node, bool partner_device)
* the device tree.
*/
for (child = node->children; child; child = child->next) {
- rc = remove_device_tree_nodes(child->ofdt_path);
+ if (kernel_dlpar_exists())
+ rc = do_dt_kernel_dlpar(child->drc_index, REMOVE);
+ else
+ rc = remove_device_tree_nodes(child->ofdt_path);
if (rc) {
say(ERROR, "%s", sw_error);
rtas_set_indicator(ISOLATION_STATE, node->drc_index,

View File

@ -1,67 +0,0 @@
commit bb766caa49f4aef036208023290f16ce7b1cf05d
Author: Haren Myneni <haren@linux.ibm.com>
Date: Tue Aug 13 14:40:26 2024 -0700
drmgr/SLOT: Add kernel interface support for device tree update
Use the following kernel interfaces for SLOT device type to update
the device tree if this feature is enabled in the kernel.
dt add index <DRC index> --> for IO add
dt remove index <DRC index> --> for IO remove
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_slot.c b/src/drmgr/drslot_chrp_slot.c
index 0966c25..180b108 100644
--- a/src/drmgr/drslot_chrp_slot.c
+++ b/src/drmgr/drslot_chrp_slot.c
@@ -71,7 +71,10 @@ release_slot(struct dr_node *slot)
if (rc)
return rc;
- rc = remove_device_tree_nodes(slot->ofdt_path);
+ if (kernel_dlpar_exists())
+ rc = do_dt_kernel_dlpar(slot->drc_index, REMOVE);
+ else
+ rc = remove_device_tree_nodes(slot->ofdt_path);
if (rc) {
acquire_drc(slot->drc_index);
return rc;
@@ -160,7 +163,6 @@ static int
acquire_slot(char *drc_name, struct dr_node **slot)
{
struct dr_connector drc;
- struct of_node *of_nodes;
char path[DR_PATH_MAX];
int rc;
@@ -180,14 +182,21 @@ acquire_slot(char *drc_name, struct dr_node **slot)
if (rc)
return rc;
- of_nodes = configure_connector(drc.index);
- if (of_nodes == NULL) {
- release_drc(drc.index, PCI_DLPAR_DEV);
- return -1;
+ if (kernel_dlpar_exists()) {
+ rc = do_dt_kernel_dlpar(drc.index, ADD);
+ } else {
+ struct of_node *of_nodes;
+
+ of_nodes = configure_connector(drc.index);
+ if (of_nodes == NULL) {
+ release_drc(drc.index, PCI_DLPAR_DEV);
+ return -1;
+ }
+
+ rc = add_device_tree_nodes(path, of_nodes);
+ free_of_node(of_nodes);
}
- rc = add_device_tree_nodes(path, of_nodes);
- free_of_node(of_nodes);
if (rc) {
say(ERROR, "add_device_tree_nodes failed at %s\n", path);
release_drc(drc.index, PCI_DLPAR_DEV);

View File

@ -1,6 +1,6 @@
Name: powerpc-utils Name: powerpc-utils
Version: 1.3.12 Version: 1.3.13
Release: 7%{?dist} Release: 1%{?dist}
Summary: PERL-based scripts for maintaining and servicing PowerPC systems Summary: PERL-based scripts for maintaining and servicing PowerPC systems
License: GPL-2.0-only License: GPL-2.0-only
@ -10,25 +10,6 @@ Source1: nx-gzip.udev
Patch0: powerpc-utils-1.3.11-manpages.patch Patch0: powerpc-utils-1.3.11-manpages.patch
# upstream patches # upstream patches
# drmgr support
Patch10: powerpc-utils-1.3.12.drmgr-support-01.patch
Patch11: powerpc-utils-1.3.12.drmgr-support-02.patch
Patch12: powerpc-utils-1.3.12.drmgr-support-03.patch
Patch13: powerpc-utils-1.3.12.drmgr-support-04.patch
Patch14: powerpc-utils-1.3.12.drmgr-support-05.patch
Patch15: powerpc-utils-1.3.12.drmgr-support-06.patch
Patch16: powerpc-utils-1.3.12.drmgr-support-07.patch
Patch17: powerpc-utils-1.3.12.drmgr-support-08.patch
Patch18: powerpc-utils-1.3.12.drmgr-support-09.patch
Patch19: powerpc-utils-1.3.12.drmgr-support-10.patch
Patch20: powerpc-utils-1.3.12.drmgr-support-11.patch
Patch21: powerpc-utils-1.3.12.drmgr-support-12.patch
Patch22: powerpc-utils-1.3.12.drmgr-support-13.patch
Patch23: powerpc-utils-1.3.12.drmgr-support-14.patch
# lparstat -E fails to Display Correct Values for %Busy and %Idle States
Patch30: powerpc-utils-1.3.12-lparstat-fix-idle-busy-purr-spurr.patch
# ppc64_cpu: Support partial SMT level through SYS FS smt/control files
Patch31: powerpc-utils-1.3.12-support-partial-smt-level-through-sysfs.patch
ExclusiveArch: ppc %{power64} ExclusiveArch: ppc %{power64}
@ -230,6 +211,10 @@ systemctl enable hcn-init.service >/dev/null 2>&1 || :
%changelog %changelog
* 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 * Mon Nov 18 2024 Than Ngo <than@redhat.com> - 1.3.12-7
- Add, multipath - drmgr support - Add, multipath - drmgr support
- Fix, SMT state is not honored when new CPUs are added dynamically - Fix, SMT state is not honored when new CPUs are added dynamically

View File

@ -1 +1 @@
SHA512 (powerpc-utils-1.3.12.tar.gz) = 43b192ff48407d49db0f31f2f347b41f44866452f215d37fe6b7705085f57066bf508bd462ff4f0b141f0a292fe15c990dd5693512a562e11a572aa6f0891b5f SHA512 (powerpc-utils-1.3.13.tar.gz) = 81fe5588e7330cb0bac81b7106c9949e364fe0b11cc1739a4074fee54c01c363ed8af05488152c9527c56ba053c11278c6b1a2340b2e088a6f25521965e4fc62