[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN][POWERPC] Allocate Xen memory area based on the amount of memory
# HG changeset patch # User Jimi Xenidis <jimix@xxxxxxxxxxxxxx> # Node ID 234257c78627ad6577cc7d4124536bfbb7d64a60 # Parent 2985a7a12706fd6a9644572ff43775533eee2a97 [XEN][POWERPC] Allocate Xen memory area based on the amount of memory This will make sure that there is enough memory for large HTABs, as well as: - enables "xenheap_megabytes=" cmdline option - consistently reports on memory system - reduces noise in memory.c Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx> --- xen/arch/powerpc/domain_build.c | 3 xen/arch/powerpc/memory.c | 308 ++++++++++++++++++++++------------------ xen/arch/powerpc/setup.c | 3 3 files changed, 172 insertions(+), 142 deletions(-) diff -r 2985a7a12706 -r 234257c78627 xen/arch/powerpc/domain_build.c --- a/xen/arch/powerpc/domain_build.c Fri Sep 29 11:29:32 2006 -0400 +++ b/xen/arch/powerpc/domain_build.c Fri Sep 29 14:31:05 2006 -0400 @@ -178,8 +178,7 @@ int construct_dom0(struct domain *d, shadow_set_allocation(d, opt_dom0_shadow, &preempt); } while (preempt); if (shadow_get_allocation(d) == 0) - panic("shadow allocation failed 0x%x < 0x%x\n", - shadow_get_allocation(d), opt_dom0_shadow); + panic("shadow allocation failed: %dMib\n", opt_dom0_shadow); ASSERT( image_len < rma_sz ); diff -r 2985a7a12706 -r 234257c78627 xen/arch/powerpc/memory.c --- a/xen/arch/powerpc/memory.c Fri Sep 29 11:29:32 2006 -0400 +++ b/xen/arch/powerpc/memory.c Fri Sep 29 14:31:05 2006 -0400 @@ -24,7 +24,26 @@ #include "oftree.h" #include "rtas.h" +#undef DEBUG +#ifdef DEBUG +#define DBG(fmt...) printk(fmt) +#else +#define DBG(fmt...) +#endif + +/* + * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the + * page_info table and allocation bitmap. + */ +static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB; +integer_param("xenheap_megabytes", opt_xenheap_megabytes); + unsigned long xenheap_phys_end; +static uint nr_pages; +static ulong xenheap_size; +static ulong save_start; +static ulong save_end; + struct membuf { ulong start; ulong size; @@ -34,14 +53,143 @@ typedef void (*walk_mem_fn)(struct membu static ulong free_xenheap(ulong start, ulong end) { - ulong save_start; - ulong save_end; - start = ALIGN_UP(start, PAGE_SIZE); end = ALIGN_DOWN(end, PAGE_SIZE); - printk("%s: 0x%lx - 0x%lx\n", __func__, start, end); - + DBG("%s: 0x%lx - 0x%lx\n", __func__, start, end); + + /* need to do this better */ + if (save_start <= end && save_start >= start) { + DBG("%s: Go around the saved area: 0x%lx - 0x%lx\n", + __func__, save_start, save_end); + init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE)); + xenheap_size += ALIGN_DOWN(save_start, PAGE_SIZE) - start; + + init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end); + xenheap_size += end - ALIGN_UP(save_end, PAGE_SIZE); + } else { + init_xenheap_pages(start, end); + xenheap_size += end - start; + } + + return ALIGN_UP(end, PAGE_SIZE); +} + +static void set_max_page(struct membuf *mb, uint entries) +{ + int i; + + for (i = 0; i < entries; i++) { + ulong end_page; + + printk(" %016lx: %016lx\n", mb[i].start, mb[i].size); + nr_pages += mb[i].size >> PAGE_SHIFT; + + end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT; + if (end_page > max_page) + max_page = end_page; + } +} + +/* mark all memory from modules onward as unused */ +static void heap_init(struct membuf *mb, uint entries) +{ + int i; + ulong start_blk; + ulong end_blk = 0; + + for (i = 0; i < entries; i++) { + start_blk = mb[i].start; + end_blk = start_blk + mb[i].size; + + if (start_blk < xenheap_phys_end) { + if (xenheap_phys_end > end_blk) { + panic("xenheap spans LMB\n"); + } + if (xenheap_phys_end == end_blk) + continue; + + start_blk = xenheap_phys_end; + } + + init_boot_pages(start_blk, end_blk); + total_pages += (end_blk - start_blk) >> PAGE_SHIFT; + } +} + +static void ofd_walk_mem(void *m, walk_mem_fn fn) +{ + ofdn_t n; + uint p_len; + struct membuf mb[8]; + static char name[] = "memory"; + + n = ofd_node_find_by_prop(m, OFD_ROOT, "device_type", name, sizeof(name)); + while (n > 0) { + + p_len = ofd_getprop(m, n, "reg", mb, sizeof (mb)); + if (p_len <= 0) { + panic("ofd_getprop(): failed\n"); + } + if (p_len > sizeof(mb)) + panic("%s: buffer is not big enuff for this firmware: " + "0x%lx < 0x%x\n", __func__, sizeof(mb), p_len); + + fn(mb, p_len / sizeof(mb[0])); + n = ofd_node_find_next(m, n); + } +} + +static void setup_xenheap(module_t *mod, int mcount) +{ + int i; + ulong freemem; + + freemem = ALIGN_UP((ulong)_end, PAGE_SIZE); + + for (i = 0; i < mcount; i++) { + u32 s; + + if (mod[i].mod_end == mod[i].mod_start) + continue; + + s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE); + + if (mod[i].mod_start > (ulong)_start && + mod[i].mod_start < (ulong)_end) { + /* mod was linked in */ + continue; + } + + if (s < freemem) + panic("module addresses must assend\n"); + + free_xenheap(freemem, s); + freemem = ALIGN_UP(mod[i].mod_end, PAGE_SIZE); + + } + + /* the rest of the xenheap, starting at the end of modules */ + free_xenheap(freemem, xenheap_phys_end); +} + +void memory_init(module_t *mod, int mcount) +{ + ulong eomem; + ulong heap_start; + ulong xh_pages; + + /* lets find out how much memory there is and set max_page */ + max_page = 0; + printk("Physical RAM map:\n"); + ofd_walk_mem((void *)oftree, set_max_page); + eomem = max_page << PAGE_SHIFT; + + if (eomem == 0){ + panic("ofd_walk_mem() failed\n"); + } + + /* find the portion of memory we need to keep safe */ save_start = oftree; save_end = oftree_end; if (rtas_base) { @@ -51,131 +199,19 @@ static ulong free_xenheap(ulong start, u save_end = rtas_end; } - /* need to do this better */ - if (save_start <= end && save_start >= start) { - printk("%s: Go around the saved area: 0x%lx - 0x%lx\n", - __func__, save_start, save_end); - init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE)); - init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end); - } else { - init_xenheap_pages(start, end); - } - - return ALIGN_UP(end, PAGE_SIZE); -} - -static void set_max_page(struct membuf *mb, uint entries) -{ - int i; - - for (i = 0; i < entries; i++) { - ulong end_page; - - end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT; - - if (end_page > max_page) - max_page = end_page; - } -} - -/* mark all memory from modules onward as unused */ -static void heap_init(struct membuf *mb, uint entries) -{ - int i; - ulong start_blk; - ulong end_blk = 0; - - for (i = 0; i < entries; i++) { - start_blk = mb[i].start; - end_blk = start_blk + mb[i].size; - - if (start_blk < xenheap_phys_end) { - if (xenheap_phys_end > end_blk) { - panic("xenheap spans LMB\n"); - } - if (xenheap_phys_end == end_blk) - continue; - - start_blk = xenheap_phys_end; - } - - init_boot_pages(start_blk, end_blk); - total_pages += (end_blk - start_blk) >> PAGE_SHIFT; - } -} - -static void ofd_walk_mem(void *m, walk_mem_fn fn) -{ - ofdn_t n; - uint p_len; - struct membuf mb[8]; - static char name[] = "memory"; - - n = ofd_node_find_by_prop(m, OFD_ROOT, "device_type", name, sizeof(name)); - while (n > 0) { - - p_len = ofd_getprop(m, n, "reg", mb, sizeof (mb)); - if (p_len <= 0) { - panic("ofd_getprop(): failed\n"); - } - if (p_len > sizeof(mb)) - panic("%s: buffer is not big enuff for this firmware: " - "0x%lx < 0x%x\n", __func__, sizeof(mb), p_len); - - fn(mb, p_len / sizeof(mb[0])); - n = ofd_node_find_next(m, n); - } -} - -static void setup_xenheap(module_t *mod, int mcount) -{ - int i; - ulong freemem; - - freemem = ALIGN_UP((ulong)_end, PAGE_SIZE); - - for (i = 0; i < mcount; i++) { - u32 s; - - if (mod[i].mod_end == mod[i].mod_start) - continue; - - s = ALIGN_DOWN(mod[i].mod_start, PAGE_SIZE); - - if (mod[i].mod_start > (ulong)_start && - mod[i].mod_start < (ulong)_end) { - /* mod was linked in */ - continue; - } - - if (s < freemem) - panic("module addresses must assend\n"); - - free_xenheap(freemem, s); - freemem = ALIGN_UP(mod[i].mod_end, PAGE_SIZE); - - } - - /* the rest of the xenheap, starting at the end of modules */ - free_xenheap(freemem, xenheap_phys_end); -} - -void memory_init(module_t *mod, int mcount) -{ - ulong eomem; - ulong heap_start, heap_size; - - printk("Physical RAM map:\n"); - - /* lets find out how much memory there is and set max_page */ - max_page = 0; - ofd_walk_mem((void *)oftree, set_max_page); - eomem = max_page << PAGE_SHIFT; - - if (eomem == 0){ - panic("ofd_walk_mem() failed\n"); - } - printk("End of RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10); + /* minimum heap has to reach to the end of all Xen required memory */ + xh_pages = ALIGN_UP(save_end, PAGE_SIZE) >> PAGE_SHIFT; + xh_pages += opt_xenheap_megabytes << (20 - PAGE_SHIFT); + + /* While we are allocating HTABS from The Xen Heap we need it to + * be larger */ + xh_pages += nr_pages >> 5; + + xenheap_phys_end = xh_pages << PAGE_SHIFT; + printk("End of Xen Area: %luMiB (%luKiB)\n", + xenheap_phys_end >> 20, xenheap_phys_end >> 10); + + printk("End of RAM: %luMiB (%luKiB)\n", eomem >> 20, eomem >> 10); /* Architecturally the first 4 pages are exception hendlers, we * will also be copying down some code there */ @@ -199,22 +235,20 @@ void memory_init(module_t *mod, int mcou panic("total_pages > max_page: 0x%lx > 0x%lx\n", total_pages, max_page); - printk("total_pages: 0x%016lx\n", total_pages); + DBG("total_pages: 0x%016lx\n", total_pages); init_frametable(); end_boot_allocator(); /* Add memory between the beginning of the heap and the beginning - * of out text */ + * of our text */ free_xenheap(heap_start, (ulong)_start); - - heap_size = xenheap_phys_end - heap_start; - printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10); - setup_xenheap(mod, mcount); + printk("Xen Heap: %luMiB (%luKiB)\n", + xenheap_size >> 20, xenheap_size >> 10); eomem = avail_domheap_pages(); - printk("Domheap pages: 0x%lx %luMB (%lukB)\n", eomem, + printk("Dom Heap: %luMiB (%luKiB)\n", (eomem << PAGE_SHIFT) >> 20, (eomem << PAGE_SHIFT) >> 10); } diff -r 2985a7a12706 -r 234257c78627 xen/arch/powerpc/setup.c --- a/xen/arch/powerpc/setup.c Fri Sep 29 11:29:32 2006 -0400 +++ b/xen/arch/powerpc/setup.c Fri Sep 29 14:31:05 2006 -0400 @@ -290,9 +290,6 @@ static void __init __start_xen(multiboot /* let synchronize until we really get going */ console_start_sync(); - /* we give the first RMA to the hypervisor */ - xenheap_phys_end = rma_size(cpu_default_rma_order_pages()); - /* Check that we have at least one Multiboot module. */ if (!(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0)) { panic("FATAL ERROR: Require at least one Multiboot module.\n"); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |