aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2010-09-14 13:19:14 -0400
committerJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2010-10-22 15:57:29 -0400
commit698bb8d14a5b577b6841acaccdf5095d3b7c7389 (patch)
tree9fb1ac50ad0384a177ac911eb516e25bf9775e53 /arch/x86
parentb5b43ced7a6e79d30df3232b37dc82c5d8dfa843 (diff)
xen: limit extra memory to a certain ratio of base
If extra memory is very much larger than the base memory size then all of the base memory can be filled with structures reserved to describe the extra memory, leaving no space for anything else. Even at the maximum ratio there will be little space for anything else, but this change is intended to at least allow the system to boot rather than crash mysteriously. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/xen/setup.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 1e85e26efa69..6c9039e92f81 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -37,6 +37,18 @@ extern void xen_syscall32_target(void);
37/* Amount of extra memory space we add to the e820 ranges */ 37/* Amount of extra memory space we add to the e820 ranges */
38phys_addr_t xen_extra_mem_start, xen_extra_mem_size; 38phys_addr_t xen_extra_mem_start, xen_extra_mem_size;
39 39
40/*
41 * The maximum amount of extra memory compared to the base size. The
42 * main scaling factor is the size of struct page. At extreme ratios
43 * of base:extra, all the base memory can be filled with page
44 * structures for the extra memory, leaving no space for anything
45 * else.
46 *
47 * 10x seems like a reasonable balance between scaling flexibility and
48 * leaving a practically usable system.
49 */
50#define EXTRA_MEM_RATIO (10)
51
40static __init void xen_add_extra_mem(unsigned long pages) 52static __init void xen_add_extra_mem(unsigned long pages)
41{ 53{
42 u64 size = (u64)pages * PAGE_SIZE; 54 u64 size = (u64)pages * PAGE_SIZE;
@@ -134,6 +146,7 @@ char * __init xen_memory_setup(void)
134 int rc; 146 int rc;
135 struct xen_memory_map memmap; 147 struct xen_memory_map memmap;
136 unsigned long extra_pages = 0; 148 unsigned long extra_pages = 0;
149 unsigned long extra_limit;
137 int i; 150 int i;
138 151
139 max_pfn = min(MAX_DOMAIN_PAGES, max_pfn); 152 max_pfn = min(MAX_DOMAIN_PAGES, max_pfn);
@@ -196,6 +209,25 @@ char * __init xen_memory_setup(void)
196 209
197 extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820); 210 extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820);
198 211
212 /*
213 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
214 * factor the base size. On non-highmem systems, the base
215 * size is the full initial memory allocation; on highmem it
216 * is limited to the max size of lowmem, so that it doesn't
217 * get completely filled.
218 *
219 * In principle there could be a problem in lowmem systems if
220 * the initial memory is also very large with respect to
221 * lowmem, but we won't try to deal with that here.
222 */
223 extra_limit = min(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
224 max_pfn + extra_pages);
225
226 if (extra_limit >= max_pfn)
227 extra_pages = extra_limit - max_pfn;
228 else
229 extra_pages = 0;
230
199 xen_add_extra_mem(extra_pages); 231 xen_add_extra_mem(extra_pages);
200 232
201 return "Xen"; 233 return "Xen";