[PATCH 3/3] powerpc/pseries: Add bitmap to track updated LMBs

Nathan Fontenot nfont at linux.vnet.ibm.com
Sat Aug 27 07:04:08 AEST 2016


Recent updates to the PAPR for memory hotplug has now made the
reserved field of the ibm,dynamic-memory property a capabilities
field. To support this update we can no longer use the reserved field
to track which LMBs have been updated during a DLPAR operation.

This patch adds a bitfield to track any LMBs that are updated during
a DLPAR operation so that we can roll back to the state proior to the
DLPAR operation if an error occurs.

Signed-off-by: Nathan Fontenot <nfont at linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/hotplug-memory.c |   25 ++++++++++-------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index a0371d1..4be1b61 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -27,6 +27,7 @@
 static struct drconf_mem {
 	u32 num_lmbs;
 	struct of_drconf_cell *lmbs;
+	unsigned long *lmb_update_map;
 } drmem;
 
 #define for_each_lmb_range(lmb, start, end)			\
@@ -46,15 +47,15 @@ static void lmb_set_aa_index(u32 lmb, u32 aa_index) {
 }
 
 static bool lmb_updated(u32 lmb) {
-	return drmem.lmbs[lmb].reserved;
+	return test_bit(lmb, drmem.lmb_update_map);
 }
 
 static void mark_lmb_updated(u32 lmb) {
-	drmem.lmbs[lmb].reserved = 1;
+	set_bit(lmb, drmem.lmb_update_map);
 }
 
-static void rm_lmb_update(u32 lmb) {
-	drmem.lmbs[lmb].reserved = 0;
+static void clear_lmb_updates(void) {
+	bitmap_zero(drmem.lmb_update_map, drmem.num_lmbs);
 }
 
 static bool lmb_reserved(u32 lmb) {
@@ -99,6 +100,11 @@ static void __init update_drconf_memory(void)
 	p = prop->value;
 	drmem.num_lmbs = be32_to_cpu(*p++);
 	drmem.lmbs = (struct of_drconf_cell *)p;
+	
+	if (!drmem.lmb_update_map) {
+		drmem.lmb_update_map = kmalloc(BITS_TO_LONGS(drmem.num_lmbs),
+					       GFP_KERNEL);
+	}
 }
 
 unsigned long pseries_memory_block_size(void)
@@ -484,8 +490,6 @@ static int dlpar_memory_remove_by_count(u32 lmbs_to_remove)
 			if (rc)
 				pr_err("Failed to add LMB back, drc index %x\n",
 				       lmb_drc_index(lmb));
-
-			rm_lmb_update(lmb);
 		}
 
 		rc = -EINVAL;
@@ -496,8 +500,6 @@ static int dlpar_memory_remove_by_count(u32 lmbs_to_remove)
 
 			pr_info("Memory at %llx was hot-removed\n",
 				lmb_base_address(lmb));
-
-			rm_lmb_update(lmb);
 		}
 		rc = 0;
 	}
@@ -588,8 +590,6 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
 			if (rc)
 				pr_err("Failed to add LMB, drc index %x\n",
 				       lmb_drc_index(lmb));
-
-			rm_lmb_update(lmb);
 		}
 		rc = -EINVAL;
 	} else {
@@ -599,8 +599,6 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index)
 
 			pr_info("Memory at %llx (drc index %x) was hot-removed\n",
 				lmb_base_address(lmb), lmb_drc_index(lmb));
-
-			rm_lmb_update(lmb);
 		}
 	}
 
@@ -732,7 +730,6 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add)
 
 			pr_info("Memory at %llx (drc index %x) was hot-added\n",
 				lmb_base_address(lmb), lmb_drc_index(lmb));
-			rm_lmb_update(lmb);
 		}
 	}
 
@@ -830,7 +827,6 @@ static int dlpar_memory_add_by_ic(u32 lmbs_to_add, u32 drc_index)
 
 			pr_info("Memory at %llx (drc index %x) was hot-added\n",
 				lmb_base_address(lmb), lmb_drc_index(lmb));
-			rm_lmb_update(lmb);
 		}
 	}
 
@@ -843,6 +839,7 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
 	int rc;
 
 	lock_device_hotplug();
+	clear_lmb_updates();
 
 	switch (hp_elog->action) {
 	case PSERIES_HP_ELOG_ACTION_ADD:



More information about the Linuxppc-dev mailing list