aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-04-01 10:20:10 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-04-01 10:20:10 +0100
commit5a3908ddfd454561546ddf9be0bf9f03ed276578 (patch)
treec4864452b2247088cbe7923190fd3e5c5ff0cf85
parent05c8070bb4eac07ff52203ef090b8881bd56560b (diff)
downloadxen-5a3908ddfd454561546ddf9be0bf9f03ed276578.tar.gz
xen-5a3908ddfd454561546ddf9be0bf9f03ed276578.tar.bz2
xen-5a3908ddfd454561546ddf9be0bf9f03ed276578.zip
Add new boot parameter 'lowmem_emergency_pool' which creates
an emergency pool of pages below 4GB (i.e., in Xen's DMA pool) which will ever be used to satisfy normal allocation requests. This is particularly useful in an i386 PAE environment to ensure that pages will always be available for allocation as page-table base directories. Usage, for example (to reserve 16MB): lowmem_emergency_pool=16M In a PAE environment, each reserved megabyte guarantees you should be able to create up to 256 processes (counted across all guests). 16MB means you're good for 4096 processes. Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--xen/common/page_alloc.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 4dff2f3679..763dafd75c 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -42,6 +42,20 @@
static char opt_badpage[100] = "";
string_param("badpage", opt_badpage);
+/*
+ * Amount of memory to reserve in a low-memory (<4GB) pool for specific
+ * allocation requests. Ordinary requests will not fall back to the
+ * lowmem emergency pool.
+ */
+static unsigned long lowmem_emergency_pool_pages;
+static void parse_lowmem_emergency_pool(char *s)
+{
+ unsigned long long bytes;
+ bytes = parse_size_and_unit(s);
+ lowmem_emergency_pool_pages = bytes >> PAGE_SHIFT;
+}
+custom_param("lowmem_emergency_pool", parse_lowmem_emergency_pool);
+
#define round_pgdown(_p) ((_p)&PAGE_MASK)
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
@@ -514,7 +528,15 @@ struct page_info *alloc_domheap_pages(
ASSERT(!in_irq());
if ( !(flags & ALLOC_DOM_DMA) )
+ {
pg = alloc_heap_pages(MEMZONE_DOM, order);
+ /* Failure? Then check if we can fall back to the DMA pool. */
+ if ( unlikely(pg == NULL) &&
+ ((order > MAX_ORDER) ||
+ (avail[MEMZONE_DMADOM] <
+ (lowmem_emergency_pool_pages + (1UL << order)))) )
+ return NULL;
+ }
if ( pg == NULL )
if ( (pg = alloc_heap_pages(MEMZONE_DMADOM, order)) == NULL )
@@ -657,7 +679,17 @@ void free_domheap_pages(struct page_info *pg, unsigned int order)
unsigned long avail_domheap_pages(void)
{
- return avail[MEMZONE_DOM] + avail[MEMZONE_DMADOM];
+ unsigned long avail_nrm, avail_dma;
+
+ avail_nrm = avail[MEMZONE_DOM];
+
+ avail_dma = avail[MEMZONE_DMADOM];
+ if ( avail_dma > lowmem_emergency_pool_pages )
+ avail_dma -= lowmem_emergency_pool_pages;
+ else
+ avail_dma = 0;
+
+ return avail_nrm + avail_dma;
}