powerpc/dlpar: Provide hotplug CPU 'readd by index' operation to support LPAR Post Migration state updates. When such changes are invoked by the PowerPC 'mobility' code, they will be queued up so that modifications to CPU properties will take place after the new property value is written to the device-tree.
Signed-off-by: Michael Bringmann <m...@linux.vnet.ibm.com> --- Changes in RFC: -- Add CPU validity check to pseries_smp_notifier --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index f78ba5d..ac08d85 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -691,6 +691,26 @@ static int dlpar_cpu_remove_by_index(u32 drc_index, bool release_drc) return rc; } +static int dlpar_cpu_readd_by_index(u32 drc_index) +{ + int rc = 0; + + pr_info("Attempting to re-add CPU, drc index %x\n", drc_index); + + rc = dlpar_cpu_remove_by_index(drc_index, false); + if (!rc) + rc = dlpar_cpu_add(drc_index, false); + + if (rc) + pr_info("Failed to update cpu at drc_index %lx\n", + (unsigned long int)drc_index); + else + pr_info("CPU at drc_index %lx was updated\n", + (unsigned long int)drc_index); + + return rc; +} + static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove) { struct device_node *dn; @@ -902,6 +922,9 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog) else rc = -EINVAL; break; + case PSERIES_HP_ELOG_ACTION_READD: + rc = dlpar_cpu_readd_by_index(drc_index); + break; default: pr_err("Invalid action (%d) specified\n", hp_elog->action); rc = -EINVAL; @@ -958,6 +981,9 @@ static int pseries_smp_notifier(struct notifier_block *nb, struct of_reconfig_data *rd = data; int err = 0; + if (strcmp(rd->dn->type, "cpu")) + return notifier_from_errno(err); + switch (action) { case OF_RECONFIG_ATTACH_NODE: err = pseries_add_processor(rd->dn); @@ -965,6 +991,12 @@ static int pseries_smp_notifier(struct notifier_block *nb, case OF_RECONFIG_DETACH_NODE: pseries_remove_processor(rd->dn); break; + case OF_RECONFIG_UPDATE_PROPERTY: + if (!strcmp(rd->prop->name, "ibm,associativity")) + dlpar_queue_action(PSERIES_HP_ELOG_RESOURCE_CPU, + PSERIES_HP_ELOG_ACTION_READD, + be32_to_cpu(rd->dn->phandle)); + break; } return notifier_from_errno(err); }