ia64/xen-unstable

changeset 14083:3746b3d4f301

alloc_boot_pages() allocates downwards from high memory.
This conserves low memory.

Provide new function alloc_boot_low_pages() for those callers who
actually require lowmem pages (e.g., below 4GB).

Based on a patch by Chris Lalancette <clalance@redhat.com>

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Feb 22 15:26:21 2007 +0000 (2007-02-22)
parents 9e35371a3caa
children da37c365b375
files xen/arch/x86/setup.c xen/common/page_alloc.c xen/include/xen/mm.h
line diff
     1.1 --- a/xen/arch/x86/setup.c	Thu Feb 22 15:22:16 2007 +0000
     1.2 +++ b/xen/arch/x86/setup.c	Thu Feb 22 15:26:21 2007 +0000
     1.3 @@ -508,7 +508,6 @@ void __init __start_xen(multiboot_info_t
     1.4          unsigned long kdump_start, kdump_size, k;
     1.5  
     1.6          /* Mark images pages as free for now. */
     1.7 -
     1.8          init_boot_pages(initial_images_start, initial_images_end);
     1.9  
    1.10          kdump_start = kexec_crash_area.start;
    1.11 @@ -526,17 +525,14 @@ void __init __start_xen(multiboot_info_t
    1.12          kdump_size >>= PAGE_SHIFT;
    1.13  
    1.14          /* Allocate pages for Kdump memory area. */
    1.15 -
    1.16 -        k = alloc_boot_pages_at(kdump_size, kdump_start);
    1.17 -        if ( k != kdump_start )
    1.18 +        if ( !reserve_boot_pages(kdump_start, kdump_size) )
    1.19              panic("Unable to reserve Kdump memory\n");
    1.20  
    1.21          /* Allocate pages for relocated initial images. */
    1.22 -
    1.23          k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
    1.24          k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
    1.25  
    1.26 -        k = alloc_boot_pages(k, 1);
    1.27 +        k = alloc_boot_low_pages(k, 1);
    1.28          if ( k == 0 )
    1.29              panic("Unable to allocate initial images memory\n");
    1.30  
     2.1 --- a/xen/common/page_alloc.c	Thu Feb 22 15:22:16 2007 +0000
     2.2 +++ b/xen/common/page_alloc.c	Thu Feb 22 15:26:21 2007 +0000
     2.3 @@ -95,9 +95,10 @@ static unsigned long scrub_pages;
     2.4  static unsigned long *alloc_bitmap;
     2.5  #define PAGES_PER_MAPWORD (sizeof(unsigned long) * 8)
     2.6  
     2.7 -#define allocated_in_map(_pn)                 \
     2.8 -( !! (alloc_bitmap[(_pn)/PAGES_PER_MAPWORD] & \
     2.9 -     (1UL<<((_pn)&(PAGES_PER_MAPWORD-1)))) )
    2.10 +#define allocated_in_map(_pn)                       \
    2.11 +({  unsigned long ___pn = (_pn);                    \
    2.12 +    !!(alloc_bitmap[___pn/PAGES_PER_MAPWORD] &      \
    2.13 +       (1UL<<(___pn&(PAGES_PER_MAPWORD-1)))); })
    2.14  
    2.15  /*
    2.16   * Hint regarding bitwise arithmetic in map_{alloc,free}:
    2.17 @@ -240,36 +241,65 @@ void init_boot_pages(paddr_t ps, paddr_t
    2.18      }
    2.19  }
    2.20  
    2.21 -unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at)
    2.22 +int reserve_boot_pages(unsigned long first_pfn, unsigned long nr_pfns)
    2.23  {
    2.24      unsigned long i;
    2.25  
    2.26      for ( i = 0; i < nr_pfns; i++ )
    2.27 -        if ( allocated_in_map(pfn_at + i) )
    2.28 +        if ( allocated_in_map(first_pfn + i) )
    2.29               break;
    2.30  
    2.31 -    if ( i == nr_pfns )
    2.32 +    if ( i != nr_pfns )
    2.33 +        return 0;
    2.34 +
    2.35 +    map_alloc(first_pfn, nr_pfns);
    2.36 +    return 1;
    2.37 +}
    2.38 +
    2.39 +unsigned long alloc_boot_low_pages(
    2.40 +    unsigned long nr_pfns, unsigned long pfn_align)
    2.41 +{
    2.42 +    unsigned long pg, i;
    2.43 +
    2.44 +    /* Search forwards to obtain lowest available range. */
    2.45 +    for ( pg = first_valid_mfn & ~(pfn_align-1);
    2.46 +          (pg + nr_pfns) < max_page;
    2.47 +          pg = (pg + i + pfn_align - 1) & ~(pfn_align - 1) )
    2.48      {
    2.49 -        map_alloc(pfn_at, nr_pfns);
    2.50 -        return pfn_at;
    2.51 +        for ( i = 0; i < nr_pfns; i++ )
    2.52 +            if ( allocated_in_map(pg+i) )
    2.53 +                break;
    2.54 +        if ( i == nr_pfns )
    2.55 +        {
    2.56 +            map_alloc(pg, nr_pfns);
    2.57 +            return pg;
    2.58 +        }
    2.59      }
    2.60  
    2.61      return 0;
    2.62  }
    2.63  
    2.64 -unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align)
    2.65 +unsigned long alloc_boot_pages(
    2.66 +    unsigned long nr_pfns, unsigned long pfn_align)
    2.67  {
    2.68 -    unsigned long pg;
    2.69 +    unsigned long pg, i;
    2.70  
    2.71 -    pg = first_valid_mfn & ~(pfn_align-1);
    2.72 -    while ( (pg + nr_pfns) < max_page )
    2.73 +    /* Search backwards to obtain highest available range. */
    2.74 +    for ( pg = (max_page - nr_pfns) & ~(pfn_align - 1);
    2.75 +          pg >= first_valid_mfn;
    2.76 +          pg = (pg + i - nr_pfns) & ~(pfn_align - 1) )
    2.77      {
    2.78 -        if ( alloc_boot_pages_at(nr_pfns, pg) != 0 )
    2.79 -            break;
    2.80 -        pg += pfn_align;
    2.81 +        for ( i = 0; i < nr_pfns; i++ )
    2.82 +            if ( allocated_in_map(pg+i) )
    2.83 +                break;
    2.84 +        if ( i == nr_pfns )
    2.85 +        {
    2.86 +            map_alloc(pg, nr_pfns);
    2.87 +            return pg;
    2.88 +        }
    2.89      }
    2.90  
    2.91 -    return pg;
    2.92 +    return 0;
    2.93  }
    2.94  
    2.95  
     3.1 --- a/xen/include/xen/mm.h	Thu Feb 22 15:22:16 2007 +0000
     3.2 +++ b/xen/include/xen/mm.h	Thu Feb 22 15:26:21 2007 +0000
     3.3 @@ -39,8 +39,11 @@ struct page_info;
     3.4  /* Boot-time allocator. Turns into generic allocator after bootstrap. */
     3.5  paddr_t init_boot_allocator(paddr_t bitmap_start);
     3.6  void init_boot_pages(paddr_t ps, paddr_t pe);
     3.7 -unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align);
     3.8 -unsigned long alloc_boot_pages_at(unsigned long nr_pfns, unsigned long pfn_at);
     3.9 +unsigned long alloc_boot_pages(
    3.10 +    unsigned long nr_pfns, unsigned long pfn_align);
    3.11 +unsigned long alloc_boot_low_pages(
    3.12 +    unsigned long nr_pfns, unsigned long pfn_align);
    3.13 +int reserve_boot_pages(unsigned long first_pfn, unsigned long nr_pfns);
    3.14  void end_boot_allocator(void);
    3.15  
    3.16  /* Generic allocator. These functions are *not* interrupt-safe. */