diff mbox series

[v2] mpipl: Rework memory reservation for OPAL dump

Message ID 20200210161635.2125-1-hegdevasant@linux.vnet.ibm.com
State Accepted
Headers show
Series [v2] mpipl: Rework memory reservation for OPAL dump | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (179d53dfcca30436777b0c748d530a979bbc8a45)
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present

Commit Message

Vasant Hegde Feb. 10, 2020, 4:16 p.m. UTC
During boot, OPAL reserves memory required to capture OPAL dump and
architected register data. During MPIPL, hostboot will copy OPAL dump
to this memory. Post MPIPL kernel will use this memory to create opalcore.
We use mem_reserve_fw() for this reservation. At present this reservation
happens late in the init path. It may clash with memory allocated by
local_alloc().

We have two option to fix above issue:
  - Use local_alloc() for allocating memory for OPAL dump
    This works fine on first boot. We can use this method to reserve
    memory. But Post MPIPL we still want to reserve destination
    memory to make sure no one is stomping this area. Also this reservation
    might have happened in between other local_allocations. So in Post MPIPL
    boot allocator may not find enough memory in first region for other
    local_alloc() requests and may throw mem_alloc() error before trying to
    allocate from other regions.

  - Early memory reservation for OPAL dump
    Allocate and reserve memory just after memory region init.


This patch uses second approach to fix reservation issue.

Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
 core/init.c         |  7 ++++++
 core/opal-dump.c    | 53 +++++++++++++++++++++++++--------------------
 include/opal-dump.h |  3 +++
 3 files changed, 40 insertions(+), 23 deletions(-)

Comments

Vasant Hegde Feb. 10, 2020, 4:31 p.m. UTC | #1
On 2/10/20 9:46 PM, Vasant Hegde wrote:
> During boot, OPAL reserves memory required to capture OPAL dump and
> architected register data. During MPIPL, hostboot will copy OPAL dump
> to this memory. Post MPIPL kernel will use this memory to create opalcore.
> We use mem_reserve_fw() for this reservation. At present this reservation
> happens late in the init path. It may clash with memory allocated by
> local_alloc().
> 
> We have two option to fix above issue:
>    - Use local_alloc() for allocating memory for OPAL dump
>      This works fine on first boot. We can use this method to reserve
>      memory. But Post MPIPL we still want to reserve destination
>      memory to make sure no one is stomping this area. Also this reservation
>      might have happened in between other local_allocations. So in Post MPIPL
>      boot allocator may not find enough memory in first region for other
>      local_alloc() requests and may throw mem_alloc() error before trying to
>      allocate from other regions.
> 
>    - Early memory reservation for OPAL dump
>      Allocate and reserve memory just after memory region init. >
> 
> This patch uses second approach to fix reservation issue.
> 
> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>


Missed to mention changes in v2:
   - V1 fix borke mambo boot as it assumed `opal_node` is created before memory 
region init. Its fixed in v2.

-Vasant
Oliver O'Halloran Feb. 17, 2020, 4 a.m. UTC | #2
On Tue, Feb 11, 2020 at 3:31 AM Vasant Hegde
<hegdevasant@linux.vnet.ibm.com> wrote:
>
> On 2/10/20 9:46 PM, Vasant Hegde wrote:
> > During boot, OPAL reserves memory required to capture OPAL dump and
> > architected register data. During MPIPL, hostboot will copy OPAL dump
> > to this memory. Post MPIPL kernel will use this memory to create opalcore.
> > We use mem_reserve_fw() for this reservation. At present this reservation
> > happens late in the init path. It may clash with memory allocated by
> > local_alloc().
> >
> > We have two option to fix above issue:
> >    - Use local_alloc() for allocating memory for OPAL dump
> >      This works fine on first boot. We can use this method to reserve
> >      memory. But Post MPIPL we still want to reserve destination
> >      memory to make sure no one is stomping this area. Also this reservation
> >      might have happened in between other local_allocations. So in Post MPIPL
> >      boot allocator may not find enough memory in first region for other
> >      local_alloc() requests and may throw mem_alloc() error before trying to
> >      allocate from other regions.
> >
> >    - Early memory reservation for OPAL dump
> >      Allocate and reserve memory just after memory region init. >
> >
> > This patch uses second approach to fix reservation issue.
> >
> > Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
>
>
> Missed to mention changes in v2:
>    - V1 fix borke mambo boot as it assumed `opal_node` is created before memory
> region init. Its fixed in v2.

Merged as b0e024216a3b1d35aa2273b6f64742db7ae49861.

We should fix the region splitting so it handles splitting a region
with memory allocations a little more gracefully. Oh well.

>
> -Vasant
>
diff mbox series

Patch

diff --git a/core/init.c b/core/init.c
index 339462e5d..53572e5e7 100644
--- a/core/init.c
+++ b/core/init.c
@@ -1150,6 +1150,13 @@  void __noreturn __nomcount main_cpu_entry(const void *fdt)
 	 */
 	mem_region_init();
 
+	/*
+	 * Reserve memory required to capture OPAL dump. This should be done
+	 * immediately after mem_region_init to avoid any clash with local
+	 * memory allocation.
+	 */
+	opal_mpipl_reserve_mem();
+
 	/* Reserve HOMER and OCC area */
 	homer_init();
 
diff --git a/core/opal-dump.c b/core/opal-dump.c
index 380a71bdd..1a43688cf 100644
--- a/core/opal-dump.c
+++ b/core/opal-dump.c
@@ -65,6 +65,7 @@  static struct opal_mpipl_fadump *opal_mpipl_cpu_data;
 static u64 opal_mpipl_tags[MAX_OPAL_MPIPL_TAGS];
 static int opal_mpipl_max_tags = MAX_OPAL_MPIPL_TAGS;
 
+static u64 opal_dump_addr, opal_dump_size;
 
 static int opal_mpipl_add_entry(u8 region, u64 src, u64 dest, u64 size)
 {
@@ -230,28 +231,12 @@  static int opal_mpipl_remove_entry_mddt(bool remove_all, u8 region, u64 dest)
 /* Register for OPAL dump.  */
 static void opal_mpipl_register(void)
 {
-	u64 opal_dest, opal_size;
 	u64 arch_regs_dest, arch_regs_size;
 	struct proc_dump_area *proc_dump = (void *)(PROC_DUMP_AREA_BASE);
 
-	/* Get OPAL runtime size */
-	if (!dt_find_property(opal_node, "opal-runtime-size")) {
-		prlog(PR_DEBUG, "Could not get OPAL runtime size\n");
-		return;
-	}
-	opal_size = dt_prop_get_u64(opal_node, "opal-runtime-size");
-	if (!opal_size) {
-		prlog(PR_DEBUG, "OPAL runtime size is zero\n");
-		return;
-	}
-
-	/* Calculate and reserve OPAL dump destination memory */
-	opal_dest = SKIBOOT_BASE + opal_size;
-	mem_reserve_fw("ibm,firmware-dump", opal_dest, opal_size);
-
 	/* Add OPAL reservation detail to MDST/MDDT table */
 	opal_mpipl_add_entry(DUMP_REGION_OPAL_MEMORY,
-			     SKIBOOT_BASE, opal_dest, opal_size);
+			     SKIBOOT_BASE, opal_dump_addr, opal_dump_size);
 
 	/* Thread size check */
 	if (proc_dump->thread_size != 0) {
@@ -259,13 +244,9 @@  static void opal_mpipl_register(void)
 		      "but not supported.\n");
 	}
 
-	/* Calculate memory to capture CPU register data */
-	arch_regs_dest = opal_dest + opal_size;
-	arch_regs_size = nr_chips() * ARCH_REGS_DATA_SIZE_PER_CHIP;
-
 	/* Reserve memory used to capture architected register state */
-	mem_reserve_fw("ibm,firmware-arch-registers",
-		       arch_regs_dest, arch_regs_size);
+	arch_regs_dest = opal_dump_addr + opal_dump_size;
+	arch_regs_size = nr_chips() * ARCH_REGS_DATA_SIZE_PER_CHIP;
 	proc_dump->alloc_addr = cpu_to_be64(arch_regs_dest | HRMOR_BIT);
 	proc_dump->alloc_size = cpu_to_be32(arch_regs_size);
 	prlog(PR_NOTICE, "Architected register dest addr : 0x%llx, "
@@ -510,6 +491,32 @@  void opal_mpipl_save_crashing_pir(void)
 	prlog(PR_NOTICE, "Crashing PIR = 0x%x\n", this_cpu()->pir);
 }
 
+void opal_mpipl_reserve_mem(void)
+{
+	struct dt_node *opal_node, *dump_node;
+	u64 arch_regs_dest, arch_regs_size;
+
+	opal_node = dt_find_by_path(dt_root, "ibm,opal");
+	if (!opal_node)
+		return;
+
+	dump_node = dt_find_by_path(opal_node, "dump");
+	if (!dump_node)
+		return;
+
+	/* Calculcate and Reserve OPAL dump destination memory */
+	opal_dump_size = SKIBOOT_SIZE + (cpu_max_pir + 1) * STACK_SIZE;
+	opal_dump_addr = SKIBOOT_BASE + opal_dump_size;
+	mem_reserve_fw("ibm,firmware-dump",
+		       opal_dump_addr, opal_dump_size);
+
+	/* Reserve memory to capture CPU register data */
+	arch_regs_dest = opal_dump_addr + opal_dump_size;
+	arch_regs_size = nr_chips() * ARCH_REGS_DATA_SIZE_PER_CHIP;
+	mem_reserve_fw("ibm,firmware-arch-registers",
+		       arch_regs_dest, arch_regs_size);
+}
+
 void opal_mpipl_init(void)
 {
 	void *mdst_base = (void *)MDST_TABLE_BASE;
diff --git a/include/opal-dump.h b/include/opal-dump.h
index 866d11aba..30b60b3a9 100644
--- a/include/opal-dump.h
+++ b/include/opal-dump.h
@@ -124,4 +124,7 @@  extern void opal_mpipl_init(void);
 /* Save metadata before triggering MPIPL */
 void opal_mpipl_save_crashing_pir(void);
 
+/* Reserve memory to capture OPAL dump */
+extern void opal_mpipl_reserve_mem(void);
+
 #endif	/* __OPAL_DUMP_H */