# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1167950710 25200
# Node ID 5708307d0e3539227c6d1f17bfa2ed4c9c92a646
# Parent 8bf7cd060df8d137ed4e189729d63707d5697ddd
[IA64] allocate contiguous_bitmap sparsely like virtual memmap.
With dom0 memory assignment changed, memory might be sparse, so simple bitmap
may waste too much memory.
Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c | 88 ++++++++++++++++++++++--
1 files changed, 84 insertions(+), 4 deletions(-)
diff -r 8bf7cd060df8 -r 5708307d0e35
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Thu Jan 04 15:28:16
2007 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Thu Jan 04 15:45:10
2007 -0700
@@ -25,7 +25,10 @@
#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
+#include <linux/efi.h>
#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/meminit.h>
#include <asm/hypervisor.h>
#include <asm/hypercall.h>
#include <xen/interface/memory.h>
@@ -56,13 +59,90 @@ static int p2m_expose_init(void);
*/
unsigned long *contiguous_bitmap;
-void
-contiguous_bitmap_init(unsigned long end_pfn)
-{
- unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3;
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+/* Following logic is stolen from create_mem_map_table() for virtual memmap */
+static int
+create_contiguous_bitmap(u64 start, u64 end, void *arg)
+{
+ unsigned long address, start_page, end_page;
+ unsigned long bitmap_start, bitmap_end;
+ unsigned char *bitmap;
+ int node;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ bitmap_start = (unsigned long)contiguous_bitmap +
+ ((__pa(start) >> PAGE_SHIFT) >> 3);
+ bitmap_end = (unsigned long)contiguous_bitmap +
+ (((__pa(end) >> PAGE_SHIFT) + 2 * BITS_PER_LONG) >> 3);
+
+ start_page = bitmap_start & PAGE_MASK;
+ end_page = PAGE_ALIGN(bitmap_end);
+ node = paddr_to_nid(__pa(start));
+
+ bitmap = alloc_bootmem_pages_node(NODE_DATA(node),
+ end_page - start_page);
+ BUG_ON(!bitmap);
+ memset(bitmap, 0, end_page - start_page);
+
+ for (address = start_page; address < end_page; address += PAGE_SIZE) {
+ pgd = pgd_offset_k(address);
+ if (pgd_none(*pgd))
+ pgd_populate(&init_mm, pgd,
+ alloc_bootmem_pages_node(NODE_DATA(node),
+ PAGE_SIZE));
+ pud = pud_offset(pgd, address);
+
+ if (pud_none(*pud))
+ pud_populate(&init_mm, pud,
+ alloc_bootmem_pages_node(NODE_DATA(node),
+ PAGE_SIZE));
+ pmd = pmd_offset(pud, address);
+
+ if (pmd_none(*pmd))
+ pmd_populate_kernel(&init_mm, pmd,
+ alloc_bootmem_pages_node
+ (NODE_DATA(node), PAGE_SIZE));
+ pte = pte_offset_kernel(pmd, address);
+
+ if (pte_none(*pte))
+ set_pte(pte,
+ pfn_pte(__pa(bitmap + (address - start_page))
+ >> PAGE_SHIFT, PAGE_KERNEL));
+ }
+ return 0;
+}
+#endif
+
+static void
+__contiguous_bitmap_init(unsigned long size)
+{
contiguous_bitmap = alloc_bootmem_pages(size);
BUG_ON(!contiguous_bitmap);
memset(contiguous_bitmap, 0, size);
+}
+
+void
+contiguous_bitmap_init(unsigned long end_pfn)
+{
+ unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3;
+#ifndef CONFIG_VIRTUAL_MEM_MAP
+ __contiguous_bitmap_init(size);
+#else
+ unsigned long max_gap = 0;
+
+ efi_memmap_walk(find_largest_hole, (u64*)&max_gap);
+ if (max_gap < LARGE_GAP) {
+ __contiguous_bitmap_init(size);
+ } else {
+ unsigned long map_size = PAGE_ALIGN(size);
+ vmalloc_end -= map_size;
+ contiguous_bitmap = (unsigned long*)vmalloc_end;
+ efi_memmap_walk(create_contiguous_bitmap, NULL);
+ }
+#endif
}
#if 0
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|