Skip to content

Commit

Permalink
xen: allow balloon driver to use more than one memory region
Browse files Browse the repository at this point in the history
Allow the xen balloon driver to populate its list of extra pages from
more than one region of memory.  This will allow platforms to provide
(for example) a region of low memory and a region of high memory.

The maximum possible number of extra regions is 128 (== E820MAX) which
is quite large so xen_extra_mem is placed in __initdata.  This is safe
as both xen_memory_setup() and balloon_init() are in __init.

The balloon regions themselves are not altered (i.e., there is still
only the one region).

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
  • Loading branch information
David Vrabel authored and Konrad Rzeszutek Wilk committed Sep 29, 2011
1 parent b1cbf9b commit 8b5d44a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 28 deletions.
20 changes: 10 additions & 10 deletions arch/x86/xen/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ extern void xen_syscall_target(void);
extern void xen_syscall32_target(void);

/* Amount of extra memory space we add to the e820 ranges */
phys_addr_t xen_extra_mem_start, xen_extra_mem_size;
struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;

/* Number of pages released from the initial allocation. */
unsigned long xen_released_pages;
Expand All @@ -59,7 +59,7 @@ static void __init xen_add_extra_mem(unsigned long pages)
unsigned long pfn;

u64 size = (u64)pages * PAGE_SIZE;
u64 extra_start = xen_extra_mem_start + xen_extra_mem_size;
u64 extra_start = xen_extra_mem[0].start + xen_extra_mem[0].size;

if (!pages)
return;
Expand All @@ -69,7 +69,7 @@ static void __init xen_add_extra_mem(unsigned long pages)

memblock_x86_reserve_range(extra_start, extra_start + size, "XEN EXTRA");

xen_extra_mem_size += size;
xen_extra_mem[0].size += size;

xen_max_p2m_pfn = PFN_DOWN(extra_start + size);

Expand Down Expand Up @@ -242,7 +242,7 @@ char * __init xen_memory_setup(void)

memcpy(map_raw, map, sizeof(map));
e820.nr_map = 0;
xen_extra_mem_start = mem_end;
xen_extra_mem[0].start = mem_end;
for (i = 0; i < memmap.nr_entries; i++) {
unsigned long long end;

Expand Down Expand Up @@ -270,19 +270,19 @@ char * __init xen_memory_setup(void)
e820_add_region(end, delta, E820_UNUSABLE);
}

if (map[i].size > 0 && end > xen_extra_mem_start)
xen_extra_mem_start = end;
if (map[i].size > 0 && end > xen_extra_mem[0].start)
xen_extra_mem[0].start = end;

/* Add region if any remains */
if (map[i].size > 0)
e820_add_region(map[i].addr, map[i].size, map[i].type);
}
/* Align the balloon area so that max_low_pfn does not get set
* to be at the _end_ of the PCI gap at the far end (fee01000).
* Note that xen_extra_mem_start gets set in the loop above to be
* past the last E820 region. */
if (xen_initial_domain() && (xen_extra_mem_start < (1ULL<<32)))
xen_extra_mem_start = (1ULL<<32);
* Note that the start of balloon area gets set in the loop above
* to be past the last E820 region. */
if (xen_initial_domain() && (xen_extra_mem[0].start < (1ULL<<32)))
xen_extra_mem[0].start = (1ULL<<32);

/*
* In domU, the ISA region is normal, usable memory, but we
Expand Down
44 changes: 27 additions & 17 deletions drivers/xen/balloon.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,11 +555,32 @@ void free_xenballooned_pages(int nr_pages, struct page** pages)
}
EXPORT_SYMBOL(free_xenballooned_pages);

static int __init balloon_init(void)
static void __init balloon_add_region(unsigned long start_pfn,
unsigned long pages)
{
unsigned long pfn, extra_pfn_end;
struct page *page;

/*
* If the amount of usable memory has been limited (e.g., with
* the 'mem' command line parameter), don't add pages beyond
* this limit.
*/
extra_pfn_end = min(max_pfn, start_pfn + pages);

for (pfn = start_pfn; pfn < extra_pfn_end; pfn++) {
page = pfn_to_page(pfn);
/* totalram_pages and totalhigh_pages do not
include the boot-time balloon extension, so
don't subtract from it. */
__balloon_append(page);
}
}

static int __init balloon_init(void)
{
int i;

if (!xen_domain())
return -ENODEV;

Expand Down Expand Up @@ -587,23 +608,12 @@ static int __init balloon_init(void)

/*
* Initialize the balloon with pages from the extra memory
* region (see arch/x86/xen/setup.c).
*
* If the amount of usable memory has been limited (e.g., with
* the 'mem' command line parameter), don't add pages beyond
* this limit.
* regions (see arch/x86/xen/setup.c).
*/
extra_pfn_end = min(max_pfn,
(unsigned long)PFN_DOWN(xen_extra_mem_start
+ xen_extra_mem_size));
for (pfn = PFN_UP(xen_extra_mem_start);
pfn < extra_pfn_end;
pfn++) {
page = pfn_to_page(pfn);
/* totalram_pages and totalhigh_pages do not include the boot-time
balloon extension, so don't subtract from it. */
__balloon_append(page);
}
for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++)
if (xen_extra_mem[i].size)
balloon_add_region(PFN_UP(xen_extra_mem[i].start),
PFN_DOWN(xen_extra_mem[i].size));

return 0;
}
Expand Down
10 changes: 9 additions & 1 deletion include/xen/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@

#include <asm/xen/page.h>

extern phys_addr_t xen_extra_mem_start, xen_extra_mem_size;
struct xen_memory_region {
phys_addr_t start;
phys_addr_t size;
};

#define XEN_EXTRA_MEM_MAX_REGIONS 128 /* == E820MAX */

extern __initdata
struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS];

extern unsigned long xen_released_pages;

Expand Down

0 comments on commit 8b5d44a

Please sign in to comment.