direct-io.hg

changeset 13455:5708307d0e35

[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@valinux.co.jp>
author awilliam@xenbuild2.aw
date Thu Jan 04 15:45:10 2007 -0700 (2007-01-04)
parents 8bf7cd060df8
children 2d4807ed1056
files linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c	Thu Jan 04 15:28:16 2007 -0700
     1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c	Thu Jan 04 15:45:10 2007 -0700
     1.3 @@ -25,7 +25,10 @@
     1.4  #include <linux/bootmem.h>
     1.5  #include <linux/module.h>
     1.6  #include <linux/vmalloc.h>
     1.7 +#include <linux/efi.h>
     1.8  #include <asm/page.h>
     1.9 +#include <asm/pgalloc.h>
    1.10 +#include <asm/meminit.h>
    1.11  #include <asm/hypervisor.h>
    1.12  #include <asm/hypercall.h>
    1.13  #include <xen/interface/memory.h>
    1.14 @@ -56,13 +59,90 @@ static int p2m_expose_init(void);
    1.15   */
    1.16  unsigned long *contiguous_bitmap;
    1.17  
    1.18 +#ifdef CONFIG_VIRTUAL_MEM_MAP
    1.19 +/* Following logic is stolen from create_mem_map_table() for virtual memmap */
    1.20 +static int
    1.21 +create_contiguous_bitmap(u64 start, u64 end, void *arg)
    1.22 +{
    1.23 +	unsigned long address, start_page, end_page;
    1.24 +	unsigned long bitmap_start, bitmap_end;
    1.25 +	unsigned char *bitmap;
    1.26 +	int node;
    1.27 +	pgd_t *pgd;
    1.28 +	pud_t *pud;
    1.29 +	pmd_t *pmd;
    1.30 +	pte_t *pte;
    1.31 +
    1.32 +	bitmap_start = (unsigned long)contiguous_bitmap +
    1.33 +	               ((__pa(start) >> PAGE_SHIFT) >> 3);
    1.34 +	bitmap_end = (unsigned long)contiguous_bitmap +
    1.35 +	             (((__pa(end) >> PAGE_SHIFT) + 2 * BITS_PER_LONG) >> 3);
    1.36 +
    1.37 +	start_page = bitmap_start & PAGE_MASK;
    1.38 +	end_page = PAGE_ALIGN(bitmap_end);
    1.39 +	node = paddr_to_nid(__pa(start));
    1.40 +
    1.41 +	bitmap = alloc_bootmem_pages_node(NODE_DATA(node),
    1.42 +	                                  end_page - start_page);
    1.43 +	BUG_ON(!bitmap);
    1.44 +	memset(bitmap, 0, end_page - start_page);
    1.45 +
    1.46 +	for (address = start_page; address < end_page; address += PAGE_SIZE) {
    1.47 +		pgd = pgd_offset_k(address);
    1.48 +		if (pgd_none(*pgd))
    1.49 +			pgd_populate(&init_mm, pgd,
    1.50 +			             alloc_bootmem_pages_node(NODE_DATA(node),
    1.51 +			                                      PAGE_SIZE));
    1.52 +		pud = pud_offset(pgd, address);
    1.53 +
    1.54 +		if (pud_none(*pud))
    1.55 +			pud_populate(&init_mm, pud,
    1.56 +			             alloc_bootmem_pages_node(NODE_DATA(node),
    1.57 +			                                      PAGE_SIZE));
    1.58 +		pmd = pmd_offset(pud, address);
    1.59 +
    1.60 +		if (pmd_none(*pmd))
    1.61 +			pmd_populate_kernel(&init_mm, pmd,
    1.62 +			                    alloc_bootmem_pages_node
    1.63 +			                    (NODE_DATA(node), PAGE_SIZE));
    1.64 +		pte = pte_offset_kernel(pmd, address);
    1.65 +
    1.66 +		if (pte_none(*pte))
    1.67 +			set_pte(pte,
    1.68 +			        pfn_pte(__pa(bitmap + (address - start_page))
    1.69 +			                >> PAGE_SHIFT, PAGE_KERNEL));
    1.70 +	}
    1.71 +	return 0;
    1.72 +}
    1.73 +#endif
    1.74 +
    1.75 +static void
    1.76 +__contiguous_bitmap_init(unsigned long size)
    1.77 +{
    1.78 +	contiguous_bitmap = alloc_bootmem_pages(size);
    1.79 +	BUG_ON(!contiguous_bitmap);
    1.80 +	memset(contiguous_bitmap, 0, size);
    1.81 +}
    1.82 +
    1.83  void
    1.84  contiguous_bitmap_init(unsigned long end_pfn)
    1.85  {
    1.86  	unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3;
    1.87 -	contiguous_bitmap = alloc_bootmem_pages(size);
    1.88 -	BUG_ON(!contiguous_bitmap);
    1.89 -	memset(contiguous_bitmap, 0, size);
    1.90 +#ifndef CONFIG_VIRTUAL_MEM_MAP
    1.91 +	__contiguous_bitmap_init(size);
    1.92 +#else
    1.93 +	unsigned long max_gap = 0;
    1.94 +
    1.95 +	efi_memmap_walk(find_largest_hole, (u64*)&max_gap);
    1.96 +	if (max_gap < LARGE_GAP) {
    1.97 +		__contiguous_bitmap_init(size);
    1.98 +	} else {
    1.99 +		unsigned long map_size = PAGE_ALIGN(size);
   1.100 +		vmalloc_end -= map_size;
   1.101 +		contiguous_bitmap = (unsigned long*)vmalloc_end;
   1.102 +		efi_memmap_walk(create_contiguous_bitmap, NULL);
   1.103 +	}
   1.104 +#endif
   1.105  }
   1.106  
   1.107  #if 0