All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration
@ 2017-11-16 17:50 Michael Bringmann
  2017-11-16 17:50 ` [PATCH V2 1/3] hotplug/mobility: Apply assoc updates for Post Migration Topo Michael Bringmann
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Michael Bringmann @ 2017-11-16 17:50 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Michael Bringmann, Nathan Fontenot, John Allen,
	Tyrel Datwyler, Thomas Falcon

The migration of LPARs across Power systems affects many attributes
including that of the associativity of memory blocks and CPUs.  The
patches in this set execute when a system is coming up fresh upon a
migration target.  They are intended to,

* Recognize changes to the associativity of memory and CPUs recorded
  in internal data structures when compared to the latest copies in
  the device tree (e.g. ibm,dynamic-memory, ibm,dynamic-memory-v2,
  cpus),
* Recognize changes to the associativity mapping (e.g. ibm,
  associativity-lookup-arrays), locate all assigned memory blocks
  corresponding to each changed row, and readd all such blocks.
* Generate calls to other code layers to reset the data structures
  related to associativity of the CPUs and memory.
* Re-register the 'changed' entities into the target system.
  Re-registration of CPUs and memory blocks mostly entails acting as
  if they have been newly hot-added into the target system.

Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>

Michael Bringmann (3):
  hotplug/mobility: Apply assoc lookup updates for Post Migration Topo
  postmigration/memory: Review assoc lookup array changes
  postmigration/memory: Associativity & 'ibm,dynamic-memory-v2'
---
Changes in V2:
  -- Try to improve patch header documentation.
  -- Remove unnecessary spacing changes from patch

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH V2 1/3] hotplug/mobility: Apply assoc updates for Post Migration Topo
  2017-11-16 17:50 [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration Michael Bringmann
@ 2017-11-16 17:50 ` Michael Bringmann
  2017-11-20 16:04   ` Nathan Fontenot
  2017-11-16 17:51 ` [PATCH V2 2/3] postmigration/memory: Review assoc lookup array changes Michael Bringmann
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Michael Bringmann @ 2017-11-16 17:50 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Michael Bringmann, Nathan Fontenot, John Allen,
	Tyrel Datwyler, Thomas Falcon

hotplug/mobility: Recognize more changes to the associativity of
memory blocks described by the 'ibm,dynamic-memory' and 'cpu'
properties when processing the topology of LPARS in Post Migration
events.  Previous efforts only recognized whether a memory block's
assignment had changed in the property.  Changes here include:

* Checking the aa_index values of the old/new properties and 'readd'
  any block for which the setting has changed.
* Checking for changes in cpus and submitting 'readd' ops for them.
* Creating some common support routines for the submission of memory
  or cpu 'readd' operations.

Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in V2:
  -- Try to improve patch header documentation.
---
 arch/powerpc/platforms/pseries/hotplug-cpu.c    |   64 +++++++++++++++++++++++
 arch/powerpc/platforms/pseries/hotplug-memory.c |    6 ++
 arch/powerpc/platforms/pseries/mobility.c       |   47 +++++++++++++----
 arch/powerpc/platforms/pseries/pseries.h        |    2 +
 4 files changed, 109 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index fadb95e..d127c3a 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -634,6 +634,27 @@ static int dlpar_cpu_remove_by_index(u32 drc_index)
 	return rc;
 }
 
+static int dlpar_cpu_readd_by_index(u32 drc_index)
+{
+	int rc = 0;
+
+	pr_info("Attempting to update CPU, drc index %x\n", drc_index);
+
+	if (dlpar_cpu_remove_by_index(drc_index))
+		rc = -EINVAL;
+	else if (dlpar_cpu_add(drc_index))
+		rc = -EINVAL;
+
+	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;
@@ -824,6 +845,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;
@@ -874,6 +898,42 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
 
 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 
+static int pseries_update_drconf_cpu(struct of_reconfig_data *pr)
+{
+	u32 old_entries, new_entries;
+	__be32 *p, *old_assoc, *new_assoc;
+
+	if (strcmp(pr->dn->type, "cpu"))
+		return 0;
+
+	/* The first int of the property is the number of domains's
+	 * described.  This is followed by an array of level values.
+	 */
+	p = (__be32 *) pr->old_prop->value;
+	if (!p)
+		return -EINVAL;
+	old_entries = be32_to_cpu(*p++);
+	old_assoc = p;
+
+	p = (__be32 *)pr->prop->value;
+	if (!p)
+		return -EINVAL;
+	new_entries = be32_to_cpu(*p++);
+	new_assoc = p;
+
+	if (old_entries == new_entries) {
+		int sz = old_entries * sizeof(int);
+
+		if (!memcmp(old_assoc, new_assoc, sz))
+			pseries_cpu_readd_by_index(pr->dn->phandle);
+
+	} else {
+		pseries_cpu_readd_by_index(pr->dn->phandle);
+	}
+
+	return 0;
+}
+
 static int pseries_smp_notifier(struct notifier_block *nb,
 				unsigned long action, void *data)
 {
@@ -887,6 +947,10 @@ 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"))
+			err = pseries_update_drconf_cpu(rd);
+		break;
 	}
 	return notifier_from_errno(err);
 }
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 1d48ab4..c61cfc6 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -1160,6 +1160,12 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
 					  memblock_size);
 			rc = (rc < 0) ? -EINVAL : 0;
 			break;
+		} else if ((be32_to_cpu(old_drmem[i].aa_index) !=
+					be32_to_cpu(new_drmem[i].aa_index)) &&
+				(be32_to_cpu(new_drmem[i].flags) &
+					DRCONF_MEM_ASSIGNED)) {
+			pseries_memory_readd_by_index(
+				be32_to_cpu(new_drmem[i].drc_index));
 		}
 	}
 	return rc;
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index f7042ad..7c19b23 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -239,9 +239,30 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
 	return rc;
 }
 
+static void pseries_readd_by_index(int resource, __be32 phandle)
+{
+	struct pseries_hp_errorlog hp_elog;
+
+	hp_elog.resource = resource;
+	hp_elog.action = PSERIES_HP_ELOG_ACTION_READD;
+	hp_elog.id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
+	hp_elog._drc_u.drc_index = phandle;
+
+	queue_hotplug_event(&hp_elog, NULL, NULL);
+}
+
+void pseries_memory_readd_by_index(__be32 phandle)
+{
+	pseries_readd_by_index(PSERIES_HP_ELOG_RESOURCE_MEM, phandle);
+}
+
+void pseries_cpu_readd_by_index(__be32 phandle)
+{
+	pseries_readd_by_index(PSERIES_HP_ELOG_RESOURCE_CPU, phandle);
+}
+
 static void prrn_update_node(__be32 phandle)
 {
-	struct pseries_hp_errorlog *hp_elog;
 	struct device_node *dn;
 
 	/*
@@ -254,18 +275,21 @@ static void prrn_update_node(__be32 phandle)
 		return;
 	}
 
-	hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL);
-	if(!hp_elog)
-		return;
+	pseries_memory_readd_by_index(phandle);
+}
 
-	hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM;
-	hp_elog->action = PSERIES_HP_ELOG_ACTION_READD;
-	hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
-	hp_elog->_drc_u.drc_index = phandle;
+static void prrn_update_node_other(s32 scope, __be32 phandle)
+{
+	struct device_node *dn;
+	__be32 drc_index = be32_to_cpu(phandle);
 
-	queue_hotplug_event(hp_elog, NULL, NULL);
+	dn = of_find_node_by_phandle(drc_index);
+	if (dn) {
+		of_node_put(dn);
 
-	kfree(hp_elog);
+		if (!strcmp(dn->type, "cpu"))
+			pseries_cpu_readd_by_index(phandle);
+	}
 }
 
 int pseries_devicetree_update(s32 scope)
@@ -309,6 +333,9 @@ int pseries_devicetree_update(s32 scope)
 
 					if (scope == PRRN_SCOPE)
 						prrn_update_node(phandle);
+					else
+						prrn_update_node_other(
+							scope, phandle);
 
 					break;
 				case ADD_DT_NODE:
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 4470a31..b9a69a6 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -55,6 +55,7 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog,
 			 struct completion *hotplug_done, int *rc);
 #ifdef CONFIG_MEMORY_HOTPLUG
 int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
+extern void pseries_memory_readd_by_index(__be32 drc_index);
 #else
 static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
 {
@@ -64,6 +65,7 @@ static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
 
 #ifdef CONFIG_HOTPLUG_CPU
 int dlpar_cpu(struct pseries_hp_errorlog *hp_elog);
+extern void pseries_cpu_readd_by_index(__be32 drc_index);
 #else
 static inline int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
 {

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH V2 2/3] postmigration/memory: Review assoc lookup array changes
  2017-11-16 17:50 [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration Michael Bringmann
  2017-11-16 17:50 ` [PATCH V2 1/3] hotplug/mobility: Apply assoc updates for Post Migration Topo Michael Bringmann
@ 2017-11-16 17:51 ` Michael Bringmann
  2017-11-16 17:51 ` [PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2 Michael Bringmann
  2017-11-28 22:30 ` [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration Michael Bringmann
  3 siblings, 0 replies; 9+ messages in thread
From: Michael Bringmann @ 2017-11-16 17:51 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Michael Bringmann, Nathan Fontenot, John Allen,
	Tyrel Datwyler, Thomas Falcon

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 <mwb@linux.vnet.ibm.com>
---
Changes in V2:
  -- Remove unnecessary spacing changes
---
 arch/powerpc/platforms/pseries/hotplug-memory.c |  119 +++++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index c61cfc6..b37e6ad 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -1171,6 +1171,122 @@ 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;
+
+	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)) {
+			pseries_memory_readd_by_index(
+				be32_to_cpu(drmem[i].drc_index));
+		}
+	}
+
+	return 0;
+}
+
+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;
+}
+
 static int pseries_memory_notifier(struct notifier_block *nb,
 				   unsigned long action, void *data)
 {
@@ -1187,6 +1303,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);

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2
  2017-11-16 17:50 [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration Michael Bringmann
  2017-11-16 17:50 ` [PATCH V2 1/3] hotplug/mobility: Apply assoc updates for Post Migration Topo Michael Bringmann
  2017-11-16 17:51 ` [PATCH V2 2/3] postmigration/memory: Review assoc lookup array changes Michael Bringmann
@ 2017-11-16 17:51 ` Michael Bringmann
  2017-11-20 16:14   ` Nathan Fontenot
  2017-11-28 22:30 ` [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration Michael Bringmann
  3 siblings, 1 reply; 9+ messages in thread
From: Michael Bringmann @ 2017-11-16 17:51 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Michael Bringmann, Nathan Fontenot, John Allen,
	Tyrel Datwyler, Thomas Falcon

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 <mwb@linux.vnet.ibm.com>
---
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	0x00000008
 #define DRCONF_MEM_AI_INVALID	0x00000040
 #define DRCONF_MEM_RESERVED	0x00000080
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,
+							&old_base_addr,
+							memblock_size,
+							&old_drmem,
+							last_old_drmem)) {
+				if ((be32_to_cpu(old_drmem->flags) &
+						DRCONF_MEM_ASSIGNED) &&
+				    (!(be32_to_cpu(new_drmem->flags) &
+						DRCONF_MEM_ASSIGNED))) {
+					rc = pseries_remove_memblock(
+						old_base_addr,
+						memblock_size);
+				} else if ((!(be32_to_cpu(old_drmem->flags) &
+						DRCONF_MEM_ASSIGNED)) &&
+					   (be32_to_cpu(new_drmem->flags) &
+						DRCONF_MEM_ASSIGNED)) {
+					rc = memblock_add(
+						old_base_addr, memblock_size);
+				} else if ((be32_to_cpu(old_drmem->aa_index) !=
+					    be32_to_cpu(new_drmem->aa_index)) &&
+					   (be32_to_cpu(new_drmem->flags) &
+						DRCONF_MEM_ASSIGNED)) {
+					pseries_memory_readd_by_index(
+						new_drc_index+j);
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
 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)
+static int pseries_update_ala_memory_aai_v1(int aa_index,
+				struct property *dmprop)
 {
 	struct of_drconf_cell *drmem;
 	u32 entries;
@@ -1208,11 +1305,47 @@ static int pseries_update_ala_memory_aai(int aa_index,
 	return 0;
 }
 
+static int pseries_update_ala_memory_aai_v2(int aa_index,
+				struct property *dmprop)
+{
+	struct of_drconf_cell_v2 *drmem;
+	u32 entries;
+	__be32 *p;
+	int i;
+
+	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_v2 entries. Get the number of entries
+	 * and skip to the array of of_drconf_cell_v2's.
+	 */
+	entries = be32_to_cpu(*p++);
+	drmem = (struct of_drconf_cell_v2 *)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)) {
+			int j;
+			int lim = be32_to_cpu(drmem->num_seq_lmbs);
+			u32 drc_index = be32_to_cpu(drmem->drc_index);
+
+			for (j = 0; j < lim; j++)
+				pseries_memory_readd_by_index(drc_index+j);
+		}
+	}
+
+	return 0;
+}
+
 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;
+	bool v1 = true;
 	__be32 *p;
 	int i, lim;
 
@@ -1225,8 +1358,13 @@ static int pseries_update_ala_memory(struct of_reconfig_data *pr)
 
 	dmprop = of_find_property(dn, "ibm,dynamic-memory", NULL);
 	if (!dmprop) {
-		of_node_put(dn);
-		return -ENODEV;
+		v1 = false;
+		dmprop = of_find_property(dn, "ibm,dynamic-memory-v2",
+					NULL);
+		if (!dmprop) {
+			of_node_put(dn);
+			return -ENODEV;
+		}
 	}
 
 	/*
@@ -1268,19 +1406,30 @@ static int pseries_update_ala_memory(struct of_reconfig_data *pr)
 						new_ala.array_sz))
 				continue;
 
-			pseries_update_ala_memory_aai(i, dmprop);
+			if (v1)
+				pseries_update_ala_memory_aai_v1(i, dmprop);
+			else
+				pseries_update_ala_memory_aai_v2(i, dmprop);
 		}
 
-		for (i = lim; i < new_ala.n_arrays; i++)
-			pseries_update_ala_memory_aai(i, dmprop);
+		for (i = lim; i < new_ala.n_arrays; i++) {
+			if (v1)
+				pseries_update_ala_memory_aai_v1(i, dmprop);
+			else
+				pseries_update_ala_memory_aai_v2(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);
+		for (i = 0; i < lim; i++) {
+			if (v1)
+				pseries_update_ala_memory_aai_v1(i, dmprop);
+			else
+				pseries_update_ala_memory_aai_v2(i, dmprop);
+		}
 	}
 
 	of_node_put(dn);
@@ -1303,6 +1452,8 @@ 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,dynamic-memory-v2"))
+			err = pseries_update_drconf_memory_v2(rd);
 		if (!strcmp(rd->prop->name,
 				"ibm,associativity-lookup-arrays"))
 			err = pseries_update_ala_memory(rd);

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH V2 1/3] hotplug/mobility: Apply assoc updates for Post Migration Topo
  2017-11-16 17:50 ` [PATCH V2 1/3] hotplug/mobility: Apply assoc updates for Post Migration Topo Michael Bringmann
@ 2017-11-20 16:04   ` Nathan Fontenot
  2017-11-27 19:52     ` Michael Bringmann
  0 siblings, 1 reply; 9+ messages in thread
From: Nathan Fontenot @ 2017-11-20 16:04 UTC (permalink / raw)
  To: Michael Bringmann, linuxppc-dev
  Cc: Michael Ellerman, John Allen, Tyrel Datwyler, Thomas Falcon

On 11/16/2017 11:50 AM, Michael Bringmann wrote:
> hotplug/mobility: Recognize more changes to the associativity of
> memory blocks described by the 'ibm,dynamic-memory' and 'cpu'
> properties when processing the topology of LPARS in Post Migration
> events.  Previous efforts only recognized whether a memory block's
> assignment had changed in the property.  Changes here include:
> 
> * Checking the aa_index values of the old/new properties and 'readd'
>   any block for which the setting has changed.
> * Checking for changes in cpus and submitting 'readd' ops for them.
> * Creating some common support routines for the submission of memory
>   or cpu 'readd' operations.
> 
> Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
> ---
> Changes in V2:
>   -- Try to improve patch header documentation.
> ---
>  arch/powerpc/platforms/pseries/hotplug-cpu.c    |   64 +++++++++++++++++++++++
>  arch/powerpc/platforms/pseries/hotplug-memory.c |    6 ++
>  arch/powerpc/platforms/pseries/mobility.c       |   47 +++++++++++++----
>  arch/powerpc/platforms/pseries/pseries.h        |    2 +
>  4 files changed, 109 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
> index fadb95e..d127c3a 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
> @@ -634,6 +634,27 @@ static int dlpar_cpu_remove_by_index(u32 drc_index)
>  	return rc;
>  }
> 
> +static int dlpar_cpu_readd_by_index(u32 drc_index)
> +{
> +	int rc = 0;
> +
> +	pr_info("Attempting to update CPU, drc index %x\n", drc_index);
> +
> +	if (dlpar_cpu_remove_by_index(drc_index))
> +		rc = -EINVAL;
> +	else if (dlpar_cpu_add(drc_index))
> +		rc = -EINVAL;
> +
> +	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;
> @@ -824,6 +845,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;
> @@ -874,6 +898,42 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
> 
>  #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
> 
> +static int pseries_update_drconf_cpu(struct of_reconfig_data *pr)

I think we can drop the 'drconf' piece from this function name.

I'm think you got that from the memory routines that use drconf, which
is really short for dynamic reconfiguration. This was used to state the
routine worked on memory represented in the dynamic-reconfiguration 
properties.

> +{
> +	u32 old_entries, new_entries;
> +	__be32 *p, *old_assoc, *new_assoc;
> +
> +	if (strcmp(pr->dn->type, "cpu"))
> +		return 0;
> +
> +	/* The first int of the property is the number of domains's
> +	 * described.  This is followed by an array of level values.
> +	 */
> +	p = (__be32 *) pr->old_prop->value;
> +	if (!p)
> +		return -EINVAL;
> +	old_entries = be32_to_cpu(*p++);
> +	old_assoc = p;
> +
> +	p = (__be32 *)pr->prop->value;
> +	if (!p)
> +		return -EINVAL;
> +	new_entries = be32_to_cpu(*p++);
> +	new_assoc = p;
> +
> +	if (old_entries == new_entries) {
> +		int sz = old_entries * sizeof(int);
> +
> +		if (!memcmp(old_assoc, new_assoc, sz))
> +			pseries_cpu_readd_by_index(pr->dn->phandle);
> +
> +	} else {
> +		pseries_cpu_readd_by_index(pr->dn->phandle);
> +	}
> +
> +	return 0;
> +}
> +
>  static int pseries_smp_notifier(struct notifier_block *nb,
>  				unsigned long action, void *data)
>  {
> @@ -887,6 +947,10 @@ 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"))
> +			err = pseries_update_drconf_cpu(rd);
> +		break;
>  	}
>  	return notifier_from_errno(err);
>  }
> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
> index 1d48ab4..c61cfc6 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
> @@ -1160,6 +1160,12 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
>  					  memblock_size);
>  			rc = (rc < 0) ? -EINVAL : 0;
>  			break;
> +		} else if ((be32_to_cpu(old_drmem[i].aa_index) !=
> +					be32_to_cpu(new_drmem[i].aa_index)) &&
> +				(be32_to_cpu(new_drmem[i].flags) &
> +					DRCONF_MEM_ASSIGNED)) {
> +			pseries_memory_readd_by_index(
> +				be32_to_cpu(new_drmem[i].drc_index));
>  		}
>  	}
>  	return rc;
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index f7042ad..7c19b23 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -239,9 +239,30 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
>  	return rc;
>  }
> 
> +static void pseries_readd_by_index(int resource, __be32 phandle)
> +{
> +	struct pseries_hp_errorlog hp_elog;
> +
> +	hp_elog.resource = resource;
> +	hp_elog.action = PSERIES_HP_ELOG_ACTION_READD;
> +	hp_elog.id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
> +	hp_elog._drc_u.drc_index = phandle;
> +
> +	queue_hotplug_event(&hp_elog, NULL, NULL);
> +}
> +
> +void pseries_memory_readd_by_index(__be32 phandle)
> +{
> +	pseries_readd_by_index(PSERIES_HP_ELOG_RESOURCE_MEM, phandle);
> +}
> +
> +void pseries_cpu_readd_by_index(__be32 phandle)
> +{
> +	pseries_readd_by_index(PSERIES_HP_ELOG_RESOURCE_CPU, phandle);
> +}
> +
>  static void prrn_update_node(__be32 phandle)
>  {
> -	struct pseries_hp_errorlog *hp_elog;
>  	struct device_node *dn;
> 
>  	/*
> @@ -254,18 +275,21 @@ static void prrn_update_node(__be32 phandle)
>  		return;
>  	}
> 
> -	hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL);
> -	if(!hp_elog)
> -		return;
> +	pseries_memory_readd_by_index(phandle);
> +}
> 
> -	hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM;
> -	hp_elog->action = PSERIES_HP_ELOG_ACTION_READD;
> -	hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
> -	hp_elog->_drc_u.drc_index = phandle;
> +static void prrn_update_node_other(s32 scope, __be32 phandle)
> +{
> +	struct device_node *dn;
> +	__be32 drc_index = be32_to_cpu(phandle);
> 
> -	queue_hotplug_event(hp_elog, NULL, NULL);
> +	dn = of_find_node_by_phandle(drc_index);
> +	if (dn) {
> +		of_node_put(dn);
> 
> -	kfree(hp_elog);
> +		if (!strcmp(dn->type, "cpu"))
> +			pseries_cpu_readd_by_index(phandle);
> +	}
>  }
> 
>  int pseries_devicetree_update(s32 scope)
> @@ -309,6 +333,9 @@ int pseries_devicetree_update(s32 scope)
> 
>  					if (scope == PRRN_SCOPE)
>  						prrn_update_node(phandle);
> +					else
> +						prrn_update_node_other(
> +							scope, phandle);

I'm not sure I follow what you're doing here.

This call appears to do a re-add of a CPU for any CPU that has the node updated.
We don't need to do a re-add of the CPU if the affinity of the CPU has not changed.

You already have a check for that in the update to pseries_smp_notifier()
above when you add the check for updates to the affinity property. So I don't
see why this is needed here.

-Nathan

> 
>  					break;
>  				case ADD_DT_NODE:
> diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
> index 4470a31..b9a69a6 100644
> --- a/arch/powerpc/platforms/pseries/pseries.h
> +++ b/arch/powerpc/platforms/pseries/pseries.h
> @@ -55,6 +55,7 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog,
>  			 struct completion *hotplug_done, int *rc);
>  #ifdef CONFIG_MEMORY_HOTPLUG
>  int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
> +extern void pseries_memory_readd_by_index(__be32 drc_index);
>  #else
>  static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
>  {
> @@ -64,6 +65,7 @@ static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
> 
>  #ifdef CONFIG_HOTPLUG_CPU
>  int dlpar_cpu(struct pseries_hp_errorlog *hp_elog);
> +extern void pseries_cpu_readd_by_index(__be32 drc_index);
>  #else
>  static inline int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
>  {
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2
  2017-11-16 17:51 ` [PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2 Michael Bringmann
@ 2017-11-20 16:14   ` Nathan Fontenot
  2017-11-27 19:53     ` Michael Bringmann
  0 siblings, 1 reply; 9+ messages in thread
From: Nathan Fontenot @ 2017-11-20 16:14 UTC (permalink / raw)
  To: Michael Bringmann, linuxppc-dev
  Cc: Michael Ellerman, John Allen, Tyrel Datwyler, Thomas Falcon

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 <mwb@linux.vnet.ibm.com>
> ---
> 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	0x00000008
>  #define DRCONF_MEM_AI_INVALID	0x00000040
>  #define DRCONF_MEM_RESERVED	0x00000080
> 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,
> +							&old_base_addr,
> +							memblock_size,
> +							&old_drmem,
> +							last_old_drmem)) {
> +				if ((be32_to_cpu(old_drmem->flags) &
> +						DRCONF_MEM_ASSIGNED) &&
> +				    (!(be32_to_cpu(new_drmem->flags) &
> +						DRCONF_MEM_ASSIGNED))) {
> +					rc = pseries_remove_memblock(
> +						old_base_addr,
> +						memblock_size);
> +				} else if ((!(be32_to_cpu(old_drmem->flags) &
> +						DRCONF_MEM_ASSIGNED)) &&
> +					   (be32_to_cpu(new_drmem->flags) &
> +						DRCONF_MEM_ASSIGNED)) {
> +					rc = memblock_add(
> +						old_base_addr, memblock_size);
> +				} else if ((be32_to_cpu(old_drmem->aa_index) !=
> +					    be32_to_cpu(new_drmem->aa_index)) &&
> +					   (be32_to_cpu(new_drmem->flags) &
> +						DRCONF_MEM_ASSIGNED)) {
> +					pseries_memory_readd_by_index(
> +						new_drc_index+j);
> +				}
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  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)
> +static int pseries_update_ala_memory_aai_v1(int aa_index,
> +				struct property *dmprop)
>  {
>  	struct of_drconf_cell *drmem;
>  	u32 entries;
> @@ -1208,11 +1305,47 @@ static int pseries_update_ala_memory_aai(int aa_index,
>  	return 0;
>  }
> 
> +static int pseries_update_ala_memory_aai_v2(int aa_index,
> +				struct property *dmprop)
> +{
> +	struct of_drconf_cell_v2 *drmem;
> +	u32 entries;
> +	__be32 *p;
> +	int i;
> +
> +	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_v2 entries. Get the number of entries
> +	 * and skip to the array of of_drconf_cell_v2's.
> +	 */
> +	entries = be32_to_cpu(*p++);
> +	drmem = (struct of_drconf_cell_v2 *)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)) {
> +			int j;
> +			int lim = be32_to_cpu(drmem->num_seq_lmbs);
> +			u32 drc_index = be32_to_cpu(drmem->drc_index);
> +
> +			for (j = 0; j < lim; j++)
> +				pseries_memory_readd_by_index(drc_index+j);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  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;
> +	bool v1 = true;
>  	__be32 *p;
>  	int i, lim;
> 
> @@ -1225,8 +1358,13 @@ static int pseries_update_ala_memory(struct of_reconfig_data *pr)
> 
>  	dmprop = of_find_property(dn, "ibm,dynamic-memory", NULL);
>  	if (!dmprop) {
> -		of_node_put(dn);
> -		return -ENODEV;
> +		v1 = false;
> +		dmprop = of_find_property(dn, "ibm,dynamic-memory-v2",
> +					NULL);
> +		if (!dmprop) {
> +			of_node_put(dn);
> +			return -ENODEV;
> +		}
>  	}
> 
>  	/*
> @@ -1268,19 +1406,30 @@ static int pseries_update_ala_memory(struct of_reconfig_data *pr)
>  						new_ala.array_sz))
>  				continue;
> 
> -			pseries_update_ala_memory_aai(i, dmprop);
> +			if (v1)
> +				pseries_update_ala_memory_aai_v1(i, dmprop);
> +			else
> +				pseries_update_ala_memory_aai_v2(i, dmprop);
>  		}
> 
> -		for (i = lim; i < new_ala.n_arrays; i++)
> -			pseries_update_ala_memory_aai(i, dmprop);
> +		for (i = lim; i < new_ala.n_arrays; i++) {
> +			if (v1)
> +				pseries_update_ala_memory_aai_v1(i, dmprop);
> +			else
> +				pseries_update_ala_memory_aai_v2(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);
> +		for (i = 0; i < lim; i++) {
> +			if (v1)
> +				pseries_update_ala_memory_aai_v1(i, dmprop);
> +			else
> +				pseries_update_ala_memory_aai_v2(i, dmprop);
> +		}
>  	}
> 
>  	of_node_put(dn);
> @@ -1303,6 +1452,8 @@ 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,dynamic-memory-v2"))
> +			err = pseries_update_drconf_memory_v2(rd);
>  		if (!strcmp(rd->prop->name,
>  				"ibm,associativity-lookup-arrays"))
>  			err = pseries_update_ala_memory(rd);
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH V2 1/3] hotplug/mobility: Apply assoc updates for Post Migration Topo
  2017-11-20 16:04   ` Nathan Fontenot
@ 2017-11-27 19:52     ` Michael Bringmann
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Bringmann @ 2017-11-27 19:52 UTC (permalink / raw)
  To: linuxppc-dev

See below.

On 11/20/2017 10:04 AM, Nathan Fontenot wrote:
> On 11/16/2017 11:50 AM, Michael Bringmann wrote:
>> hotplug/mobility: Recognize more changes to the associativity of
>> memory blocks described by the 'ibm,dynamic-memory' and 'cpu'
>> properties when processing the topology of LPARS in Post Migration
>> events.  Previous efforts only recognized whether a memory block's
>> assignment had changed in the property.  Changes here include:
>>
>> * Checking the aa_index values of the old/new properties and 'readd'
>>   any block for which the setting has changed.
>> * Checking for changes in cpus and submitting 'readd' ops for them.
>> * Creating some common support routines for the submission of memory
>>   or cpu 'readd' operations.
>>
>> Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
>> ---
>> Changes in V2:
>>   -- Try to improve patch header documentation.
>> ---
>>  arch/powerpc/platforms/pseries/hotplug-cpu.c    |   64 +++++++++++++++++++++++
>>  arch/powerpc/platforms/pseries/hotplug-memory.c |    6 ++
>>  arch/powerpc/platforms/pseries/mobility.c       |   47 +++++++++++++----
>>  arch/powerpc/platforms/pseries/pseries.h        |    2 +
>>  4 files changed, 109 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
>> index fadb95e..d127c3a 100644
>> --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
>> +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
>> @@ -634,6 +634,27 @@ static int dlpar_cpu_remove_by_index(u32 drc_index)
>>  	return rc;
>>  }
>>
>> +static int dlpar_cpu_readd_by_index(u32 drc_index)
>> +{
>> +	int rc = 0;
>> +
>> +	pr_info("Attempting to update CPU, drc index %x\n", drc_index);
>> +
>> +	if (dlpar_cpu_remove_by_index(drc_index))
>> +		rc = -EINVAL;
>> +	else if (dlpar_cpu_add(drc_index))
>> +		rc = -EINVAL;
>> +
>> +	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;
>> @@ -824,6 +845,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;
>> @@ -874,6 +898,42 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
>>
>>  #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
>>
>> +static int pseries_update_drconf_cpu(struct of_reconfig_data *pr)
> 
> I think we can drop the 'drconf' piece from this function name.
> 
> I'm think you got that from the memory routines that use drconf, which
> is really short for dynamic reconfiguration. This was used to state the
> routine worked on memory represented in the dynamic-reconfiguration 
> properties.

Okay.

> 
>> +{
>> +	u32 old_entries, new_entries;
>> +	__be32 *p, *old_assoc, *new_assoc;
>> +
>> +	if (strcmp(pr->dn->type, "cpu"))
>> +		return 0;
>> +
>> +	/* The first int of the property is the number of domains's
>> +	 * described.  This is followed by an array of level values.
>> +	 */
>> +	p = (__be32 *) pr->old_prop->value;
>> +	if (!p)
>> +		return -EINVAL;
>> +	old_entries = be32_to_cpu(*p++);
>> +	old_assoc = p;
>> +
>> +	p = (__be32 *)pr->prop->value;
>> +	if (!p)
>> +		return -EINVAL;
>> +	new_entries = be32_to_cpu(*p++);
>> +	new_assoc = p;
>> +
>> +	if (old_entries == new_entries) {
>> +		int sz = old_entries * sizeof(int);
>> +
>> +		if (!memcmp(old_assoc, new_assoc, sz))
>> +			pseries_cpu_readd_by_index(pr->dn->phandle);
>> +
>> +	} else {
>> +		pseries_cpu_readd_by_index(pr->dn->phandle);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  static int pseries_smp_notifier(struct notifier_block *nb,
>>  				unsigned long action, void *data)
>>  {
>> @@ -887,6 +947,10 @@ 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"))
>> +			err = pseries_update_drconf_cpu(rd);
>> +		break;
>>  	}
>>  	return notifier_from_errno(err);
>>  }
>> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
>> index 1d48ab4..c61cfc6 100644
>> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
>> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
>> @@ -1160,6 +1160,12 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
>>  					  memblock_size);
>>  			rc = (rc < 0) ? -EINVAL : 0;
>>  			break;
>> +		} else if ((be32_to_cpu(old_drmem[i].aa_index) !=
>> +					be32_to_cpu(new_drmem[i].aa_index)) &&
>> +				(be32_to_cpu(new_drmem[i].flags) &
>> +					DRCONF_MEM_ASSIGNED)) {
>> +			pseries_memory_readd_by_index(
>> +				be32_to_cpu(new_drmem[i].drc_index));
>>  		}
>>  	}
>>  	return rc;
>> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
>> index f7042ad..7c19b23 100644
>> --- a/arch/powerpc/platforms/pseries/mobility.c
>> +++ b/arch/powerpc/platforms/pseries/mobility.c
>> @@ -239,9 +239,30 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
>>  	return rc;
>>  }
>>
>> +static void pseries_readd_by_index(int resource, __be32 phandle)
>> +{
>> +	struct pseries_hp_errorlog hp_elog;
>> +
>> +	hp_elog.resource = resource;
>> +	hp_elog.action = PSERIES_HP_ELOG_ACTION_READD;
>> +	hp_elog.id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
>> +	hp_elog._drc_u.drc_index = phandle;
>> +
>> +	queue_hotplug_event(&hp_elog, NULL, NULL);
>> +}
>> +
>> +void pseries_memory_readd_by_index(__be32 phandle)
>> +{
>> +	pseries_readd_by_index(PSERIES_HP_ELOG_RESOURCE_MEM, phandle);
>> +}
>> +
>> +void pseries_cpu_readd_by_index(__be32 phandle)
>> +{
>> +	pseries_readd_by_index(PSERIES_HP_ELOG_RESOURCE_CPU, phandle);
>> +}
>> +
>>  static void prrn_update_node(__be32 phandle)
>>  {
>> -	struct pseries_hp_errorlog *hp_elog;
>>  	struct device_node *dn;
>>
>>  	/*
>> @@ -254,18 +275,21 @@ static void prrn_update_node(__be32 phandle)
>>  		return;
>>  	}
>>
>> -	hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL);
>> -	if(!hp_elog)
>> -		return;
>> +	pseries_memory_readd_by_index(phandle);
>> +}
>>
>> -	hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM;
>> -	hp_elog->action = PSERIES_HP_ELOG_ACTION_READD;
>> -	hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
>> -	hp_elog->_drc_u.drc_index = phandle;
>> +static void prrn_update_node_other(s32 scope, __be32 phandle)
>> +{
>> +	struct device_node *dn;
>> +	__be32 drc_index = be32_to_cpu(phandle);
>>
>> -	queue_hotplug_event(hp_elog, NULL, NULL);
>> +	dn = of_find_node_by_phandle(drc_index);
>> +	if (dn) {
>> +		of_node_put(dn);
>>
>> -	kfree(hp_elog);
>> +		if (!strcmp(dn->type, "cpu"))
>> +			pseries_cpu_readd_by_index(phandle);
>> +	}
>>  }
>>
>>  int pseries_devicetree_update(s32 scope)
>> @@ -309,6 +333,9 @@ int pseries_devicetree_update(s32 scope)
>>
>>  					if (scope == PRRN_SCOPE)
>>  						prrn_update_node(phandle);
>> +					else
>> +						prrn_update_node_other(
>> +							scope, phandle);
> 
> I'm not sure I follow what you're doing here.
> 
> This call appears to do a re-add of a CPU for any CPU that has the node updated.
> We don't need to do a re-add of the CPU if the affinity of the CPU has not changed.
> 
> You already have a check for that in the update to pseries_smp_notifier()
> above when you add the check for updates to the affinity property. So I don't
> see why this is needed here.
> 
> -Nathan

I will need to retest this patch with the suggested change.

- Michael

> 
>>
>>  					break;
>>  				case ADD_DT_NODE:
>> diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
>> index 4470a31..b9a69a6 100644
>> --- a/arch/powerpc/platforms/pseries/pseries.h
>> +++ b/arch/powerpc/platforms/pseries/pseries.h
>> @@ -55,6 +55,7 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog,
>>  			 struct completion *hotplug_done, int *rc);
>>  #ifdef CONFIG_MEMORY_HOTPLUG
>>  int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
>> +extern void pseries_memory_readd_by_index(__be32 drc_index);
>>  #else
>>  static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
>>  {
>> @@ -64,6 +65,7 @@ static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
>>
>>  #ifdef CONFIG_HOTPLUG_CPU
>>  int dlpar_cpu(struct pseries_hp_errorlog *hp_elog);
>> +extern void pseries_cpu_readd_by_index(__be32 drc_index);
>>  #else
>>  static inline int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
>>  {
>>
> 
> 

-- 
Michael W. Bringmann
Linux Technology Center
IBM Corporation
Tie-Line  363-5196
External: (512) 286-5196
Cell:       (512) 466-0650
mwb@linux.vnet.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2
  2017-11-20 16:14   ` Nathan Fontenot
@ 2017-11-27 19:53     ` Michael Bringmann
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Bringmann @ 2017-11-27 19:53 UTC (permalink / raw)
  To: linuxppc-dev

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 <mwb@linux.vnet.ibm.com>
>> ---
>> 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	0x00000008
>>  #define DRCONF_MEM_AI_INVALID	0x00000040
>>  #define DRCONF_MEM_RESERVED	0x00000080
>> 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,
>> +							&old_base_addr,
>> +							memblock_size,
>> +							&old_drmem,
>> +							last_old_drmem)) {
>> +				if ((be32_to_cpu(old_drmem->flags) &
>> +						DRCONF_MEM_ASSIGNED) &&
>> +				    (!(be32_to_cpu(new_drmem->flags) &
>> +						DRCONF_MEM_ASSIGNED))) {
>> +					rc = pseries_remove_memblock(
>> +						old_base_addr,
>> +						memblock_size);
>> +				} else if ((!(be32_to_cpu(old_drmem->flags) &
>> +						DRCONF_MEM_ASSIGNED)) &&
>> +					   (be32_to_cpu(new_drmem->flags) &
>> +						DRCONF_MEM_ASSIGNED)) {
>> +					rc = memblock_add(
>> +						old_base_addr, memblock_size);
>> +				} else if ((be32_to_cpu(old_drmem->aa_index) !=
>> +					    be32_to_cpu(new_drmem->aa_index)) &&
>> +					   (be32_to_cpu(new_drmem->flags) &
>> +						DRCONF_MEM_ASSIGNED)) {
>> +					pseries_memory_readd_by_index(
>> +						new_drc_index+j);
>> +				}
>> +			}
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  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)
>> +static int pseries_update_ala_memory_aai_v1(int aa_index,
>> +				struct property *dmprop)
>>  {
>>  	struct of_drconf_cell *drmem;
>>  	u32 entries;
>> @@ -1208,11 +1305,47 @@ static int pseries_update_ala_memory_aai(int aa_index,
>>  	return 0;
>>  }
>>
>> +static int pseries_update_ala_memory_aai_v2(int aa_index,
>> +				struct property *dmprop)
>> +{
>> +	struct of_drconf_cell_v2 *drmem;
>> +	u32 entries;
>> +	__be32 *p;
>> +	int i;
>> +
>> +	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_v2 entries. Get the number of entries
>> +	 * and skip to the array of of_drconf_cell_v2's.
>> +	 */
>> +	entries = be32_to_cpu(*p++);
>> +	drmem = (struct of_drconf_cell_v2 *)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)) {
>> +			int j;
>> +			int lim = be32_to_cpu(drmem->num_seq_lmbs);
>> +			u32 drc_index = be32_to_cpu(drmem->drc_index);
>> +
>> +			for (j = 0; j < lim; j++)
>> +				pseries_memory_readd_by_index(drc_index+j);
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  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;
>> +	bool v1 = true;
>>  	__be32 *p;
>>  	int i, lim;
>>
>> @@ -1225,8 +1358,13 @@ static int pseries_update_ala_memory(struct of_reconfig_data *pr)
>>
>>  	dmprop = of_find_property(dn, "ibm,dynamic-memory", NULL);
>>  	if (!dmprop) {
>> -		of_node_put(dn);
>> -		return -ENODEV;
>> +		v1 = false;
>> +		dmprop = of_find_property(dn, "ibm,dynamic-memory-v2",
>> +					NULL);
>> +		if (!dmprop) {
>> +			of_node_put(dn);
>> +			return -ENODEV;
>> +		}
>>  	}
>>
>>  	/*
>> @@ -1268,19 +1406,30 @@ static int pseries_update_ala_memory(struct of_reconfig_data *pr)
>>  						new_ala.array_sz))
>>  				continue;
>>
>> -			pseries_update_ala_memory_aai(i, dmprop);
>> +			if (v1)
>> +				pseries_update_ala_memory_aai_v1(i, dmprop);
>> +			else
>> +				pseries_update_ala_memory_aai_v2(i, dmprop);
>>  		}
>>
>> -		for (i = lim; i < new_ala.n_arrays; i++)
>> -			pseries_update_ala_memory_aai(i, dmprop);
>> +		for (i = lim; i < new_ala.n_arrays; i++) {
>> +			if (v1)
>> +				pseries_update_ala_memory_aai_v1(i, dmprop);
>> +			else
>> +				pseries_update_ala_memory_aai_v2(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);
>> +		for (i = 0; i < lim; i++) {
>> +			if (v1)
>> +				pseries_update_ala_memory_aai_v1(i, dmprop);
>> +			else
>> +				pseries_update_ala_memory_aai_v2(i, dmprop);
>> +		}
>>  	}
>>
>>  	of_node_put(dn);
>> @@ -1303,6 +1452,8 @@ 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,dynamic-memory-v2"))
>> +			err = pseries_update_drconf_memory_v2(rd);
>>  		if (!strcmp(rd->prop->name,
>>  				"ibm,associativity-lookup-arrays"))
>>  			err = pseries_update_ala_memory(rd);
>>
> 
> 

-- 
Michael W. Bringmann
Linux Technology Center
IBM Corporation
Tie-Line  363-5196
External: (512) 286-5196
Cell:       (512) 466-0650
mwb@linux.vnet.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration
  2017-11-16 17:50 [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration Michael Bringmann
                   ` (2 preceding siblings ...)
  2017-11-16 17:51 ` [PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2 Michael Bringmann
@ 2017-11-28 22:30 ` Michael Bringmann
  3 siblings, 0 replies; 9+ messages in thread
From: Michael Bringmann @ 2017-11-28 22:30 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Michael Ellerman, Nathan Fontenot, John Allen, Tyrel Datwyler,
	Thomas Falcon

Hello:
    I would like to pull / defer further consideration of this patch set
for a while.  I will be discussing changes here with respect to the
LMB optimizations that Nathan Fontenot is working upon.
    A revision of this patch set will be sent out somewhat later.
Thanks for your attention and assistance.

Michael

On 11/16/2017 11:50 AM, Michael Bringmann wrote:
> The migration of LPARs across Power systems affects many attributes
> including that of the associativity of memory blocks and CPUs.  The
> patches in this set execute when a system is coming up fresh upon a
> migration target.  They are intended to,
> 
> * Recognize changes to the associativity of memory and CPUs recorded
>   in internal data structures when compared to the latest copies in
>   the device tree (e.g. ibm,dynamic-memory, ibm,dynamic-memory-v2,
>   cpus),
> * Recognize changes to the associativity mapping (e.g. ibm,
>   associativity-lookup-arrays), locate all assigned memory blocks
>   corresponding to each changed row, and readd all such blocks.
> * Generate calls to other code layers to reset the data structures
>   related to associativity of the CPUs and memory.
> * Re-register the 'changed' entities into the target system.
>   Re-registration of CPUs and memory blocks mostly entails acting as
>   if they have been newly hot-added into the target system.
> 
> Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
> 
> Michael Bringmann (3):
>   hotplug/mobility: Apply assoc lookup updates for Post Migration Topo
>   postmigration/memory: Review assoc lookup array changes
>   postmigration/memory: Associativity & 'ibm,dynamic-memory-v2'
> ---
> Changes in V2:
>   -- Try to improve patch header documentation.
>   -- Remove unnecessary spacing changes from patch
> 

-- 
Michael W. Bringmann
Linux Technology Center
IBM Corporation
Tie-Line  363-5196
External: (512) 286-5196
Cell:       (512) 466-0650
mwb@linux.vnet.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-11-28 22:31 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-16 17:50 [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration Michael Bringmann
2017-11-16 17:50 ` [PATCH V2 1/3] hotplug/mobility: Apply assoc updates for Post Migration Topo Michael Bringmann
2017-11-20 16:04   ` Nathan Fontenot
2017-11-27 19:52     ` Michael Bringmann
2017-11-16 17:51 ` [PATCH V2 2/3] postmigration/memory: Review assoc lookup array changes Michael Bringmann
2017-11-16 17:51 ` [PATCH V2 3/3] postmigration/memory: Associativity & ibm,dynamic-memory-v2 Michael Bringmann
2017-11-20 16:14   ` Nathan Fontenot
2017-11-27 19:53     ` Michael Bringmann
2017-11-28 22:30 ` [PATCH V2 0/3] powerpc/hotplug: Fix affinity assoc for LPAR migration Michael Bringmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.