Re: [PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2

2017-11-27 Thread Michael Bringmann
Okay.  We can discuss that tomorrow.

On 11/20/2017 10:14 AM, Nathan Fontenot wrote:
> We may want to wait on this patch. I have been working on patches to separate
> the LMB information from the device tree property format. Once those patches
> are acceptable we can use a common routine for affinity updates.
> 
> -Nathan
> 
> On 11/16/2017 11:51 AM, Michael Bringmann wrote:
>> postmigration/memory: Now apply changes to the associativity of memory
>> blocks described by the 'ibm,dynamic-memory-v2' property regarding
>> the topology of LPARS in Post Migration events.
>>
>> * Extend the previous work done for the 'ibm,associativity-lookup-array'
>>   to apply to either property 'ibm,dynamic-memory' or
>>   'ibm,dynamic-memory-v2', whichever is present.
>> * Add new code to parse the 'ibm,dynamic-memory-v2' property looking
>>   for differences in block 'assignment', associativity indexes per
>>   block, and any other difference currently known.
>>
>> When block differences are recognized, the memory block may be removed,
>> added, or updated depending upon the state of the new device tree
>> property and differences from the migrated value of the property.
>>
>> Signed-off-by: Michael Bringmann 
>> ---
>> Changes in V2:
>>   -- Remove unnecessary spacing changes from patch.
>>   -- Improve patch description.
>> ---
>>  arch/powerpc/include/asm/prom.h |   12 ++
>>  arch/powerpc/platforms/pseries/hotplug-memory.c |  169 
>> ++-
>>  2 files changed, 172 insertions(+), 9 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/prom.h 
>> b/arch/powerpc/include/asm/prom.h
>> index 825bd59..e16ef0f 100644
>> --- a/arch/powerpc/include/asm/prom.h
>> +++ b/arch/powerpc/include/asm/prom.h
>> @@ -92,6 +92,18 @@ struct of_drconf_cell {
>>  u32 flags;
>>  };
>>
>> +/* The of_drconf_cell_v2 struct defines the layout of the LMB array
>> + * specified in the device tree property
>> + * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory-v2
>> + */
>> +struct of_drconf_cell_v2 {
>> +u32 num_seq_lmbs;
>> +u64 base_address;
>> +u32 drc_index;
>> +u32 aa_index;
>> +u32 flags;
>> +} __attribute__((packed));
>> +
>>  #define DRCONF_MEM_ASSIGNED 0x0008
>>  #define DRCONF_MEM_AI_INVALID   0x0040
>>  #define DRCONF_MEM_RESERVED 0x0080
>> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
>> b/arch/powerpc/platforms/pseries/hotplug-memory.c
>> index b37e6ad..bf9687b 100644
>> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
>> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
>> @@ -1171,14 +1171,111 @@ static int pseries_update_drconf_memory(struct 
>> of_reconfig_data *pr)
>>  return rc;
>>  }
>>
>> +static inline int pseries_memory_v2_find_drc(u32 drc_index,
>> +u64 *base_addr, unsigned long memblock_size,
>> +struct of_drconf_cell_v2 **drmem,
>> +struct of_drconf_cell_v2 *last_drmem)
>> +{
>> +struct of_drconf_cell_v2 *dm = (*drmem);
>> +
>> +while (dm < last_drmem) {
>> +if ((be32_to_cpu(dm->drc_index) <= drc_index) &&
>> +(drc_index <= (be32_to_cpu(dm->drc_index)+
>> +be32_to_cpu(dm->num_seq_lmbs)-1))) {
>> +int offset = drc_index - be32_to_cpu(dm->drc_index);
>> +(*base_addr) = be64_to_cpu(dm->base_address) +
>> +(offset * memblock_size);
>> +break;
>> +} else if (drc_index > (be32_to_cpu(dm->drc_index)+
>> +be32_to_cpu(dm->num_seq_lmbs)-1)) {
>> +dm++;
>> +(*drmem) = dm;
>> +} else if (be32_to_cpu(dm->drc_index) > drc_index) {
>> +return -1;
>> +}
>> +}
>> +
>> +return 0;
>> +}
>> +
>> +static int pseries_update_drconf_memory_v2(struct of_reconfig_data *pr)
>> +{
>> +struct of_drconf_cell_v2 *new_drmem, *old_drmem, *last_old_drmem;
>> +unsigned long memblock_size;
>> +u32 new_entries, old_entries;
>> +u64 old_base_addr;
>> +__be32 *p;
>> +int i, rc = 0;
>> +
>> +if (rtas_hp_event)
>> +return 0;
>> +
>> +memblock_size = pseries_memory_block_size();
>> +if (!memblock_size)
>> +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_v2 entries. Get the number of entries
>> + * and skip to the array of of_drconf_cell_v2's.
>> + */
>> +p = (__be32 *) pr->old_prop->value;
>> +if (!p)
>> +return -EINVAL;
>> +old_entries = be32_to_cpu(*p++);
>> +old_drmem = (struct of_drconf_cell_v2 *)p;
>> +last_old_drmem = old_drmem +
>> +(sizeof(struct of_drconf_cell_v2) * old_entries);
>> +
>> +p = (__be32 

Re: [PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2

2017-11-20 Thread Nathan Fontenot
We may want to wait on this patch. I have been working on patches to separate
the LMB information from the device tree property format. Once those patches
are acceptable we can use a common routine for affinity updates.

-Nathan

On 11/16/2017 11:51 AM, Michael Bringmann wrote:
> postmigration/memory: Now apply changes to the associativity of memory
> blocks described by the 'ibm,dynamic-memory-v2' property regarding
> the topology of LPARS in Post Migration events.
> 
> * Extend the previous work done for the 'ibm,associativity-lookup-array'
>   to apply to either property 'ibm,dynamic-memory' or
>   'ibm,dynamic-memory-v2', whichever is present.
> * Add new code to parse the 'ibm,dynamic-memory-v2' property looking
>   for differences in block 'assignment', associativity indexes per
>   block, and any other difference currently known.
> 
> When block differences are recognized, the memory block may be removed,
> added, or updated depending upon the state of the new device tree
> property and differences from the migrated value of the property.
> 
> Signed-off-by: Michael Bringmann 
> ---
> Changes in V2:
>   -- Remove unnecessary spacing changes from patch.
>   -- Improve patch description.
> ---
>  arch/powerpc/include/asm/prom.h |   12 ++
>  arch/powerpc/platforms/pseries/hotplug-memory.c |  169 
> ++-
>  2 files changed, 172 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index 825bd59..e16ef0f 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -92,6 +92,18 @@ struct of_drconf_cell {
>   u32 flags;
>  };
> 
> +/* The of_drconf_cell_v2 struct defines the layout of the LMB array
> + * specified in the device tree property
> + * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory-v2
> + */
> +struct of_drconf_cell_v2 {
> + u32 num_seq_lmbs;
> + u64 base_address;
> + u32 drc_index;
> + u32 aa_index;
> + u32 flags;
> +} __attribute__((packed));
> +
>  #define DRCONF_MEM_ASSIGNED  0x0008
>  #define DRCONF_MEM_AI_INVALID0x0040
>  #define DRCONF_MEM_RESERVED  0x0080
> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
> b/arch/powerpc/platforms/pseries/hotplug-memory.c
> index b37e6ad..bf9687b 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
> @@ -1171,14 +1171,111 @@ static int pseries_update_drconf_memory(struct 
> of_reconfig_data *pr)
>   return rc;
>  }
> 
> +static inline int pseries_memory_v2_find_drc(u32 drc_index,
> + u64 *base_addr, unsigned long memblock_size,
> + struct of_drconf_cell_v2 **drmem,
> + struct of_drconf_cell_v2 *last_drmem)
> +{
> + struct of_drconf_cell_v2 *dm = (*drmem);
> +
> + while (dm < last_drmem) {
> + if ((be32_to_cpu(dm->drc_index) <= drc_index) &&
> + (drc_index <= (be32_to_cpu(dm->drc_index)+
> + be32_to_cpu(dm->num_seq_lmbs)-1))) {
> + int offset = drc_index - be32_to_cpu(dm->drc_index);
> + (*base_addr) = be64_to_cpu(dm->base_address) +
> + (offset * memblock_size);
> + break;
> + } else if (drc_index > (be32_to_cpu(dm->drc_index)+
> + be32_to_cpu(dm->num_seq_lmbs)-1)) {
> + dm++;
> + (*drmem) = dm;
> + } else if (be32_to_cpu(dm->drc_index) > drc_index) {
> + return -1;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int pseries_update_drconf_memory_v2(struct of_reconfig_data *pr)
> +{
> + struct of_drconf_cell_v2 *new_drmem, *old_drmem, *last_old_drmem;
> + unsigned long memblock_size;
> + u32 new_entries, old_entries;
> + u64 old_base_addr;
> + __be32 *p;
> + int i, rc = 0;
> +
> + if (rtas_hp_event)
> + return 0;
> +
> + memblock_size = pseries_memory_block_size();
> + if (!memblock_size)
> + 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_v2 entries. Get the number of entries
> +  * and skip to the array of of_drconf_cell_v2's.
> +  */
> + p = (__be32 *) pr->old_prop->value;
> + if (!p)
> + return -EINVAL;
> + old_entries = be32_to_cpu(*p++);
> + old_drmem = (struct of_drconf_cell_v2 *)p;
> + last_old_drmem = old_drmem +
> + (sizeof(struct of_drconf_cell_v2) * old_entries);
> +
> + p = (__be32 *)pr->prop->value;
> + new_entries = be32_to_cpu(*p++);
> + new_drmem = (struct of_drconf_cell_v2 *)p;
> +
> + for (i = 0; i < new_entries; i++) {

[PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2

2017-11-16 Thread Michael Bringmann
postmigration/memory: Now apply changes to the associativity of memory
blocks described by the 'ibm,dynamic-memory-v2' property regarding
the topology of LPARS in Post Migration events.

* Extend the previous work done for the 'ibm,associativity-lookup-array'
  to apply to either property 'ibm,dynamic-memory' or
  'ibm,dynamic-memory-v2', whichever is present.
* Add new code to parse the 'ibm,dynamic-memory-v2' property looking
  for differences in block 'assignment', associativity indexes per
  block, and any other difference currently known.

When block differences are recognized, the memory block may be removed,
added, or updated depending upon the state of the new device tree
property and differences from the migrated value of the property.

Signed-off-by: Michael Bringmann 
---
Changes in V2:
  -- Remove unnecessary spacing changes from patch.
  -- Improve patch description.
---
 arch/powerpc/include/asm/prom.h |   12 ++
 arch/powerpc/platforms/pseries/hotplug-memory.c |  169 ++-
 2 files changed, 172 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 825bd59..e16ef0f 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -92,6 +92,18 @@ struct of_drconf_cell {
u32 flags;
 };
 
+/* The of_drconf_cell_v2 struct defines the layout of the LMB array
+ * specified in the device tree property
+ * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory-v2
+ */
+struct of_drconf_cell_v2 {
+   u32 num_seq_lmbs;
+   u64 base_address;
+   u32 drc_index;
+   u32 aa_index;
+   u32 flags;
+} __attribute__((packed));
+
 #define DRCONF_MEM_ASSIGNED0x0008
 #define DRCONF_MEM_AI_INVALID  0x0040
 #define DRCONF_MEM_RESERVED0x0080
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
b/arch/powerpc/platforms/pseries/hotplug-memory.c
index b37e6ad..bf9687b 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -1171,14 +1171,111 @@ static int pseries_update_drconf_memory(struct 
of_reconfig_data *pr)
return rc;
 }
 
+static inline int pseries_memory_v2_find_drc(u32 drc_index,
+   u64 *base_addr, unsigned long memblock_size,
+   struct of_drconf_cell_v2 **drmem,
+   struct of_drconf_cell_v2 *last_drmem)
+{
+   struct of_drconf_cell_v2 *dm = (*drmem);
+
+   while (dm < last_drmem) {
+   if ((be32_to_cpu(dm->drc_index) <= drc_index) &&
+   (drc_index <= (be32_to_cpu(dm->drc_index)+
+   be32_to_cpu(dm->num_seq_lmbs)-1))) {
+   int offset = drc_index - be32_to_cpu(dm->drc_index);
+   (*base_addr) = be64_to_cpu(dm->base_address) +
+   (offset * memblock_size);
+   break;
+   } else if (drc_index > (be32_to_cpu(dm->drc_index)+
+   be32_to_cpu(dm->num_seq_lmbs)-1)) {
+   dm++;
+   (*drmem) = dm;
+   } else if (be32_to_cpu(dm->drc_index) > drc_index) {
+   return -1;
+   }
+   }
+
+   return 0;
+}
+
+static int pseries_update_drconf_memory_v2(struct of_reconfig_data *pr)
+{
+   struct of_drconf_cell_v2 *new_drmem, *old_drmem, *last_old_drmem;
+   unsigned long memblock_size;
+   u32 new_entries, old_entries;
+   u64 old_base_addr;
+   __be32 *p;
+   int i, rc = 0;
+
+   if (rtas_hp_event)
+   return 0;
+
+   memblock_size = pseries_memory_block_size();
+   if (!memblock_size)
+   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_v2 entries. Get the number of entries
+* and skip to the array of of_drconf_cell_v2's.
+*/
+   p = (__be32 *) pr->old_prop->value;
+   if (!p)
+   return -EINVAL;
+   old_entries = be32_to_cpu(*p++);
+   old_drmem = (struct of_drconf_cell_v2 *)p;
+   last_old_drmem = old_drmem +
+   (sizeof(struct of_drconf_cell_v2) * old_entries);
+
+   p = (__be32 *)pr->prop->value;
+   new_entries = be32_to_cpu(*p++);
+   new_drmem = (struct of_drconf_cell_v2 *)p;
+
+   for (i = 0; i < new_entries; i++) {
+   int j;
+   u32 new_drc_index = be32_to_cpu(new_drmem->drc_index);
+
+   for (j = 0; j < new_drmem->num_seq_lmbs; j++) {
+   if (!pseries_memory_v2_find_drc(new_drc_index+j,
+   _base_addr,
+   memblock_size,
+