[PATCH 2/8] pseries: phyp dump: reserve-release proof-of-concept
Michael Ellerman
michael at ellerman.id.au
Tue Mar 11 12:02:21 EST 2008
On Thu, 2008-02-28 at 18:24 -0600, Manish Ahuja wrote:
> Initial patch for reserving memory in early boot, and freeing it later.
> If the previous boot had ended with a crash, the reserved memory would contain
> a copy of the crashed kernel data.
>
> Signed-off-by: Manish Ahuja <mahuja at us.ibm.com>
> Signed-off-by: Linas Vepstas <linasvepstas at gmail.com>
Hi Manish,
A few comments inline ..
> Index: 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ 2.6.25-rc1/arch/powerpc/platforms/pseries/phyp_dump.c 2008-02-28 21:57:52.000000000 -0600
> @@ -0,0 +1,105 @@
> +/*
> + * Hypervisor-assisted dump
> + *
> + * Linas Vepstas, Manish Ahuja 2008
> + * Copyright 2008 IBM Corp.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/mm.h>
> +#include <linux/pfn.h>
> +#include <linux/swap.h>
> +
> +#include <asm/page.h>
> +#include <asm/phyp_dump.h>
> +#include <asm/machdep.h>
> +#include <asm/prom.h>
> +
> +/* Global, used to communicate data between early boot and late boot */
> +static struct phyp_dump phyp_dump_global;
> +struct phyp_dump *phyp_dump_info = &phyp_dump_global;
I don't see the point of this. You have a static (ie. non-global) struct
called phyp_dump_global, then you create a pointer to it and pass that
around. It could just be:
phyp_dump.h:
extern struct phyp_dump phyp_dump_info;
phyp_dump.c:
struct phyp_dump phyp_dump_info;
phyp_dump_info.foo = bar;
I also think the struct should be called phyp_dump_info, not phyp_dump -
it contains info about phyp_dump, not the dump itself.
> +
> +/**
> + * release_memory_range -- release memory previously lmb_reserved
> + * @start_pfn: starting physical frame number
> + * @nr_pages: number of pages to free.
> + *
> + * This routine will release memory that had been previously
> + * lmb_reserved in early boot. The released memory becomes
> + * available for genreal use.
> + */
> +static void
> +release_memory_range(unsigned long start_pfn, unsigned long nr_pages)
> +{
> + struct page *rpage;
> + unsigned long end_pfn;
> + long i;
> +
> + end_pfn = start_pfn + nr_pages;
> +
> + for (i = start_pfn; i <= end_pfn; i++) {
> + rpage = pfn_to_page(i);
> + if (PageReserved(rpage)) {
> + ClearPageReserved(rpage);
> + init_page_count(rpage);
> + __free_page(rpage);
> + totalram_pages++;
> + }
> + }
> +}
> +
> +static int __init phyp_dump_setup(void)
> +{
> + unsigned long start_pfn, nr_pages;
> +
> + /* If no memory was reserved in early boot, there is nothing to do */
> + if (phyp_dump_info->init_reserve_size == 0)
> + return 0;
> +
> + /* Release memory that was reserved in early boot */
> + start_pfn = PFN_DOWN(phyp_dump_info->init_reserve_start);
> + nr_pages = PFN_DOWN(phyp_dump_info->init_reserve_size);
> + release_memory_range(start_pfn, nr_pages);
> +
> + return 0;
> +}
> +machine_subsys_initcall(pseries, phyp_dump_setup);
> +
> +int __init early_init_dt_scan_phyp_dump(unsigned long node,
> + const char *uname, int depth, void *data)
> +{
> +#ifdef CONFIG_PHYP_DUMP
> + const unsigned int *sizes;
> +
> + phyp_dump_info->phyp_dump_configured = 0;
> + phyp_dump_info->phyp_dump_is_active = 0;
> +
> + if (depth != 1 || strcmp(uname, "rtas") != 0)
> + return 0;
> +
> + if (of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL))
> + phyp_dump_info->phyp_dump_configured++;
> +
> + if (of_get_flat_dt_prop(node, "ibm,dump-kernel", NULL))
> + phyp_dump_info->phyp_dump_is_active++;
> +
> + sizes = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",
> + NULL);
> + if (!sizes)
> + return 0;
> +
> + if (sizes[0] == 1)
> + phyp_dump_info->cpu_state_size = *((unsigned long *)&sizes[1]);
> +
> + if (sizes[3] == 2)
> + phyp_dump_info->hpte_region_size =
> + *((unsigned long *)&sizes[4]);
> +#endif
This doesn't need to be inside #ifdef, you have a dummy version already
defined in the header file.
> Index: 2.6.25-rc1/arch/powerpc/kernel/prom.c
> ===================================================================
> --- 2.6.25-rc1.orig/arch/powerpc/kernel/prom.c 2008-02-28 21:54:57.000000000 -0600
> +++ 2.6.25-rc1/arch/powerpc/kernel/prom.c 2008-02-28 21:55:27.000000000 -0600
> @@ -1039,6 +1040,51 @@ static void __init early_reserve_mem(voi
> #endif
> }
>
> +#ifdef CONFIG_PHYP_DUMP
> +/**
> + * reserve_crashed_mem() - reserve all not-yet-dumped mmemory
> + *
> + * This routine may reserve memory regions in the kernel only
> + * if the system is supported and a dump was taken in last
> + * boot instance or if the hardware is supported and the
> + * scratch area needs to be setup. In other instances it returns
> + * without reserving anything. The memory in case of dump being
> + * active is freed when the dump is collected (by userland tools).
> + */
> +static void __init reserve_crashed_mem(void)
This could do with a name change IMO, eg. phyp_dump_reserve_mem() or
something.
> +{
> + unsigned long base, size;
> + if (!phyp_dump_info->phyp_dump_configured) {
> + printk(KERN_ERR "Phyp-dump not supported on this hardware\n");
> + return;
> + }
> +
> + if (phyp_dump_info->phyp_dump_is_active) {
> + /* Reserve *everything* above RMR.Area freed by userland tools*/
> + base = PHYP_DUMP_RMR_END;
> + size = lmb_end_of_DRAM() - base;
> +
> + /* XXX crashed_ram_end is wrong, since it may be beyond
> + * the memory_limit, it will need to be adjusted. */
> + lmb_reserve(base, size);
> +
> + phyp_dump_info->init_reserve_start = base;
> + phyp_dump_info->init_reserve_size = size;
> + } else {
> + size = phyp_dump_info->cpu_state_size +
> + phyp_dump_info->hpte_region_size +
> + PHYP_DUMP_RMR_END;
> + base = lmb_end_of_DRAM() - size;
> + lmb_reserve(base, size);
> + phyp_dump_info->init_reserve_start = base;
> + phyp_dump_info->init_reserve_size = size;
> + }
> +}
> +#else
> +static inline void __init reserve_crashed_mem(void) {}
> +#endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20080311/bfe0e21d/attachment.pgp>
More information about the Linuxppc-dev
mailing list