From: awilliam@xenbuild2.aw Date: Thu, 4 Jan 2007 22:45:10 +0000 (-0700) Subject: [IA64] allocate contiguous_bitmap sparsely like virtual memmap. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15431 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=003fd895c4d87ef54bfdf588986d55fec3569ea5;p=xen.git [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 --- diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c index 173a4f613a..d0bc3f92ec 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c @@ -25,7 +25,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -56,15 +59,92 @@ static int p2m_expose_init(void); */ unsigned long *contiguous_bitmap; -void -contiguous_bitmap_init(unsigned long end_pfn) +#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) { - unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3; 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 int contiguous_bitmap_test(void* p)