dd69abbd9a
- Fix, SMT state is not honored when new CPUs are added dynamically Resolves: RHEL-62938
174 lines
5.0 KiB
Diff
174 lines
5.0 KiB
Diff
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;
|
|
}
|
|
|