On 02/26/2018 02:53 PM, Michael Bringmann wrote: > postmigration/memory: In an LPAR migration scenario, the property > "ibm,associativity-lookup-arrays" may change. In the event that a > row of the array differs, locate all assigned memory blocks with that > 'aa_index' and 're-add' them to the system memory block data structures. > In the process of the 're-add', the appropriate entry of the property > 'ibm,dynamic-memory' would be updated as well as any other applicable > system data structures. > > Signed-off-by: Michael Bringmann <m...@linux.vnet.ibm.com> > --- > Changes in RFC v2: > -- Simplify code to update memory nodes during mobility checks. > Remove functions to generate extra HP_ELOG messages in favor > of direct function calls to dlpar_memory_readd_by_index. > --- > arch/powerpc/platforms/pseries/hotplug-memory.c | 120 > +++++++++++++++++++++++ > 1 file changed, 120 insertions(+) > > diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c > b/arch/powerpc/platforms/pseries/hotplug-memory.c > index 2341eae..b63181d 100644 > --- a/arch/powerpc/platforms/pseries/hotplug-memory.c > +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c > @@ -1051,6 +1051,123 @@ static int pseries_update_drconf_memory(struct > of_reconfig_data *pr) > return rc; > } > > +struct assoc_arrays { > + u32 n_arrays; > + u32 array_sz; > + const __be32 *arrays; > +}; > + > +static int pseries_update_ala_memory_aai(int aa_index, > + struct property *dmprop) > +{ > + struct of_drconf_cell *drmem; > + u32 entries; > + __be32 *p; > + int i; > + int rc = 0; > + > + p = (__be32 *) dmprop->value; > + if (!p) > + return -EINVAL; > + > + /* The first int of the property is the number of lmb's > + * described by the property. This is followed by an array > + * of of_drconf_cell entries. Get the number of entries > + * and skip to the array of of_drconf_cell's. > + */ > + entries = be32_to_cpu(*p++); > + drmem = (struct of_drconf_cell *)p; > + > + for (i = 0; i < entries; i++) { > + if ((be32_to_cpu(drmem[i].aa_index) != aa_index) && > + (be32_to_cpu(drmem[i].flags) & DRCONF_MEM_ASSIGNED)) { > + rc = dlpar_memory_readd_by_index( > + be32_to_cpu(drmem[i].drc_index)); > + } > + } > + > + return rc; > +} > + > +static int pseries_update_ala_memory(struct of_reconfig_data *pr) > +{ > + struct assoc_arrays new_ala, old_ala; > + struct device_node *dn; > + struct property *dmprop; > + __be32 *p; > + int i, lim; > + > + if (rtas_hp_event) > + return 0; > + > + dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); > + if (!dn) > + return -ENODEV; > + > + dmprop = of_find_property(dn, "ibm,dynamic-memory", NULL); > + if (!dmprop) { > + of_node_put(dn); > + return -ENODEV; > + } > + > + /* > + * The layout of the ibm,associativity-lookup-arrays > + * property is a number N indicating the number of > + * associativity arrays, followed by a number M > + * indicating the size of each associativity array, > + * followed by a list of N associativity arrays. > + */ > + > + p = (__be32 *) pr->old_prop->value; > + if (!p) { > + of_node_put(dn); > + return -EINVAL; > + } > + old_ala.n_arrays = of_read_number(p++, 1); > + old_ala.array_sz = of_read_number(p++, 1); > + old_ala.arrays = p; > + > + p = (__be32 *) pr->prop->value; > + if (!p) { > + of_node_put(dn); > + return -EINVAL; > + } > + new_ala.n_arrays = of_read_number(p++, 1); > + new_ala.array_sz = of_read_number(p++, 1); > + new_ala.arrays = p; > + > + lim = (new_ala.n_arrays > old_ala.n_arrays) ? old_ala.n_arrays : > + new_ala.n_arrays; > + > + if (old_ala.array_sz == new_ala.array_sz) { > + > + for (i = 0; i < lim; i++) { > + int index = (i * new_ala.array_sz); > + > + if (!memcmp(&old_ala.arrays[index], > + &new_ala.arrays[index], > + new_ala.array_sz)) > + continue; > + > + pseries_update_ala_memory_aai(i, dmprop); > + } > + > + for (i = lim; i < new_ala.n_arrays; i++) > + pseries_update_ala_memory_aai(i, dmprop); > + > + } else { > + /* Update all entries representing these rows; > + * as all rows have different sizes, none can > + * have equivalent values. > + */ > + for (i = 0; i < lim; i++) > + pseries_update_ala_memory_aai(i, dmprop); > + } > + > + of_node_put(dn); > + return 0; > +}
The two routines above should be updated to use the in-kernel drmem array instead of looking up the dynamic-memory property in the device tree. -Nathan > + > static int pseries_memory_notifier(struct notifier_block *nb, > unsigned long action, void *data) > { > @@ -1067,6 +1184,9 @@ static int pseries_memory_notifier(struct > notifier_block *nb, > case OF_RECONFIG_UPDATE_PROPERTY: > if (!strcmp(rd->prop->name, "ibm,dynamic-memory")) > err = pseries_update_drconf_memory(rd); > + if (!strcmp(rd->prop->name, > + "ibm,associativity-lookup-arrays")) > + err = pseries_update_ala_memory(rd); > break; > } > return notifier_from_errno(err); >