[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