powerpc/pseries: Dynamic associativity-lookup-arrays updating
cover powerpc/pseries: Dynamic associativity-lookup-arrays updating
The ibm,dynamic-reconfiguration-memory/ibm,associativity-lookup-arrays property used to track the associativity for LMBs assigned to a system may not contain all of the possible associativity arrays for the system at boot time. When a LMB is added to the system and its associativity array is not present in the lookup array we need to update the lookup array to contain the new associativity array.
The first patch splits the code that creates a clone of a property into its own routine so this can be used for cloning any of the properties used during memory hotplug.
The second patch updates the associativity lookup code to dynamically add new associativity arrays to the lookup array if they are not present.
-Nathan
hotplug-memory.c | 131 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 92 insertions(+), 39 deletions(-)
PATCH 1/2 powerpc/pseries: Move property cloning into its own routine
Move property cloning code into its own routine
Split the pieces of dlpar_clone_drconf_property() that create a copy of the property struct into its own routine. This allows for creating clones of more than just the ibm,dynamic-memory property used in memory hotplug.
--- arch/powerpc/platforms/pseries/hotplug-memory.c | 38 ++++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-)
arch/powerpc/platforms/pseries/hotplug-memory.c +26 -12
@@ -69,13 +69,36 @@ unsigned long pseries_memory_block_size(void)return memblock_size; } -static void dlpar_free_drconf_property (struct property *prop) +static void dlpar_free_property (struct property *prop) {kfree (prop->name);kfree (prop->value);kfree (prop); } +static struct property *dlpar_clone_property (struct property *prop, +u32 prop_size) +{ +struct property *new_prop; + + new_prop =kzalloc (sizeof (*new_prop),GFP_KERNEL ); +if (!new_prop) +return NULL ; + + new_prop->name =kstrdup (prop->name,GFP_KERNEL ); + new_prop->value =kzalloc (prop_size,GFP_KERNEL ); +if (!new_prop->name || !new_prop->value) { +dlpar_free_property (new_prop); +return NULL ; + } + +memcpy (new_prop->value, prop->value, prop->length); + new_prop->length = prop_size; + +of_property_set_flag (new_prop,OF_DYNAMIC ); +return new_prop; +} +static struct property *dlpar_clone_drconf_property (struct device_node *dn) {struct property *prop, *new_prop;
@@ -87,19 +110,10 @@ static struct property *dlpar_clone_drconf_property(struct device_node *dn)if (!prop)return NULL ; - new_prop =kzalloc (sizeof (*new_prop),GFP_KERNEL ); + new_prop =dlpar_clone_property (prop, prop->length);if (!new_prop)return NULL ; - new_prop->name =kstrdup (prop->name,GFP_KERNEL ); - new_prop->value =kmemdup (prop->value, prop->length,GFP_KERNEL ); -if (!new_prop->name || !new_prop->value) { -dlpar_free_drconf_property (new_prop); -return NULL ; - } - - new_prop->length = prop->length; -/* Convert the property to cpu endian-ness */ p = new_prop->value; *p =be32_to_cpu (*p);
@@ -718,7 +732,7 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)break ; } -dlpar_free_drconf_property (prop); +dlpar_free_property (prop); dlpar_memory_out:of_node_put (dn);
Michael Ellerman
reviewerRe: [1/2] powerpc/pseries: Move property cloning into its own routine
Quoted 8 lines · Nathan Fontenot
Move property cloning code into its own routine
Split the pieces of
dlpar_clone_drconf_property()that create a copy of the property struct into its own routine. This allows for creating clones of more than just the ibm,dynamic-memory property used in memory hotplug.Signed-off-by Nathan Fontenot <[email protected]>
Series applied to powerpc next, thanks.
https://git.kernel.org/powerpc/c/c2101c9039fe2a005f7b4138e0
cheers
PATCH 2/2 powerpc/pseries: Dynamic add entires to associativity lookup array
In reply to Nathan FontenotDynamically add entries to the associativity lookup array
The ibm,associativity-lookup-arrays property may only contain associativity arrays for LMBs present at boot time. When hotplug adding a LMB its associativity array may not be in the associativity lookup array, this patch adds the ability to add new entries to the associativity lookup array.
--- arch/powerpc/platforms/pseries/hotplug-memory.c | 93 ++++++++++++++++------- 1 file changed, 66 insertions(+), 27 deletions(-)
arch/powerpc/platforms/pseries/hotplug-memory.c +66 -27
@@ -191,14 +191,72 @@ static int dlpar_update_device_tree_lmb(struct of_drconf_cell *lmb)return 0 ; } +static u32 find_aa_index (struct device_node *dr_node, +struct property *ala_prop,const u32 *lmb_assoc) +{ +u32 *assoc_arrays; +u32 aa_index; +int aa_arrays, aa_array_entries, aa_array_sz; +int i, index; + +/* The ibm,associativity-lookup-arrays property is defined to be +* a 32-bit value specifying the number of associativity arrays +* followed by a 32-bitvalue specifying the number of entries per +* array, followed by the associativity arrays. +*/ + assoc_arrays = ala_prop->value; + + aa_arrays =be32_to_cpu (assoc_arrays[0 ]); + aa_array_entries =be32_to_cpu (assoc_arrays[1 ]); + aa_array_sz = aa_array_entries *sizeof (u32); + + aa_index =-1 ; +for (i =0 ; i < aa_arrays; i++) { + index = (i * aa_array_entries) +2 ; + +if (memcmp (&assoc_arrays[index], &lmb_assoc[1 ], aa_array_sz)) +continue ; + + aa_index = i; +break ; + } + +if (aa_index ==-1 ) { +struct property *new_prop; +u32 new_prop_size; + + new_prop_size = ala_prop->length + aa_array_sz; + new_prop =dlpar_clone_property (ala_prop, new_prop_size); +if (!new_prop) +return -1 ; + + assoc_arrays = new_prop->value; + +/* increment the number of entries in the lookup array */ + assoc_arrays[0 ] =cpu_to_be32 (aa_arrays +1 ); + +/* copy the new associativity into the lookup array */ + index = aa_arrays * aa_array_entries +2 ; +memcpy (&assoc_arrays[index], &lmb_assoc[1 ], aa_array_sz); + +of_update_property (dr_node, new_prop); + +/* The associativity lookup array index for this lmb is +* number of entries - 1 since we added its associativity +* to the end of the lookup array. +*/ + aa_index =be32_to_cpu (assoc_arrays[0 ]) -1 ; + } + +return aa_index; +} +static u32 lookup_lmb_associativity_index (struct of_drconf_cell *lmb) {struct device_node *parent, *lmb_node, *dr_node; +struct property *ala_prop;const u32 *lmb_assoc; -const u32 *assoc_arrays;u32 aa_index; -int aa_arrays, aa_array_entries, aa_array_sz; -int i; parent =of_find_node_by_path ("/" );if (!parent)
@@ -222,34 +280,15 @@ static u32 lookup_lmb_associativity_index(struct of_drconf_cell *lmb)return -ENODEV ; } - assoc_arrays =of_get_property (dr_node, -"ibm,associativity-lookup-arrays" , -NULL ); -of_node_put (dr_node); -if (!assoc_arrays) { + ala_prop =of_find_property (dr_node,"ibm,associativity-lookup-arrays" , +NULL ); +if (!ala_prop) { +of_node_put (dr_node);dlpar_free_cc_nodes (lmb_node);return -ENODEV ; } -/* The ibm,associativity-lookup-arrays property is defined to be -* a 32-bit value specifying the number of associativity arrays -* followed by a 32-bitvalue specifying the number of entries per -* array, followed by the associativity arrays. -*/ - aa_arrays =be32_to_cpu (assoc_arrays[0 ]); - aa_array_entries =be32_to_cpu (assoc_arrays[1 ]); - aa_array_sz = aa_array_entries *sizeof (u32); - - aa_index =-1 ; -for (i =0 ; i < aa_arrays; i++) { -int indx = (i * aa_array_entries) +2 ; - -if (memcmp (&assoc_arrays[indx], &lmb_assoc[1 ], aa_array_sz)) -continue ; - - aa_index = i; -break ; - } + aa_index =find_aa_index (dr_node, ala_prop, lmb_assoc);dlpar_free_cc_nodes (lmb_node);return aa_index;