# 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
|