Update to 1.3.13
Resolves: RHEL-24535
This commit is contained in:
parent
dd69abbd9a
commit
7757efa247
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
|
||||||
|
@ -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);
|
|
@ -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;
|
|
@ -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)
|
|
@ -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,
|
|
@ -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 *);
|
|
@ -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);
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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,
|
|
@ -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)
|
|
||||||
{
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
@ -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;
|
|
||||||
}
|
|
@ -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
|
|
@ -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);
|
|
@ -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,
|
|
@ -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);
|
|
@ -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
|
||||||
|
2
sources
2
sources
@ -1 +1 @@
|
|||||||
SHA512 (powerpc-utils-1.3.12.tar.gz) = 43b192ff48407d49db0f31f2f347b41f44866452f215d37fe6b7705085f57066bf508bd462ff4f0b141f0a292fe15c990dd5693512a562e11a572aa6f0891b5f
|
SHA512 (powerpc-utils-1.3.13.tar.gz) = 81fe5588e7330cb0bac81b7106c9949e364fe0b11cc1739a4074fee54c01c363ed8af05488152c9527c56ba053c11278c6b1a2340b2e088a6f25521965e4fc62
|
||||||
|
Loading…
Reference in New Issue
Block a user