[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 18/19] mini-os: balloon up in case of oom
If a memory shortage is detected balloon up. Be careful to always leave some pages free as ballooning up might need some memory, too: - new p2m frames - page tables for addressing new p2m frame - new frame for page allocation bitmap - page table for addressing new page allocation bitmap frame - page tables for addressing new 1:1 mapped frames For the moment we only balloon up synchronously when memory shortage is detected in allocation routines with irqs on. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> Reviewed-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx> --- V3: Reverse chk_free_pages() return value as requested by Samuel Thibault --- balloon.c | 32 ++++++++++++++++++++++++++++++++ include/balloon.h | 11 +++++++++++ mm.c | 4 +++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/balloon.c b/balloon.c index 07ef532..afec757 100644 --- a/balloon.c +++ b/balloon.c @@ -126,3 +126,35 @@ int balloon_up(unsigned long n_pages) return rc; } + +static int in_balloon; + +int chk_free_pages(unsigned long needed) +{ + unsigned long n_pages; + + /* No need for ballooning if plenty of space available. */ + if ( needed + BALLOON_EMERGENCY_PAGES <= nr_free_pages ) + return 1; + + /* If we are already ballooning up just hope for the best. */ + if ( in_balloon ) + return 1; + + /* Interrupts disabled can't be handled right now. */ + if ( irqs_disabled() ) + return 1; + + in_balloon = 1; + + while ( needed + BALLOON_EMERGENCY_PAGES > nr_free_pages ) + { + n_pages = needed + BALLOON_EMERGENCY_PAGES - nr_free_pages; + if ( !balloon_up(n_pages) ) + break; + } + + in_balloon = 0; + + return needed <= nr_free_pages; +} diff --git a/include/balloon.h b/include/balloon.h index 5ec1bbb..d8710ad 100644 --- a/include/balloon.h +++ b/include/balloon.h @@ -26,6 +26,12 @@ #ifdef CONFIG_BALLOON +/* + * Always keep some pages free for allocations while ballooning or + * interrupts disabled. + */ +#define BALLOON_EMERGENCY_PAGES 64 + extern unsigned long nr_max_pages; extern unsigned long virt_kernel_area_end; extern unsigned long nr_mem_pages; @@ -37,12 +43,17 @@ void arch_remap_p2m(unsigned long max_pfn); void mm_alloc_bitmap_remap(void); int arch_expand_p2m(unsigned long max_pfn); void arch_pfn_add(unsigned long pfn, unsigned long mfn); +int chk_free_pages(unsigned long needed); #else /* CONFIG_BALLOON */ static inline void get_max_pages(void) { } static inline void arch_remap_p2m(unsigned long max_pfn) { } static inline void mm_alloc_bitmap_remap(void) { } +static inline int chk_free_pages(unsigned long needed) +{ + return needed <= nr_free_pages; +} #endif /* CONFIG_BALLOON */ #endif /* _BALLOON_H_ */ diff --git a/mm.c b/mm.c index 5364079..b1f8f34 100644 --- a/mm.c +++ b/mm.c @@ -209,6 +209,8 @@ unsigned long alloc_pages(int order) chunk_head_t *alloc_ch, *spare_ch; chunk_tail_t *spare_ct; + if ( !chk_free_pages(1UL << order) ) + goto no_memory; /* Find smallest order which can satisfy the request. */ for ( i = order; i < FREELIST_SIZE; i++ ) { @@ -343,7 +345,7 @@ void *sbrk(ptrdiff_t increment) if (new_brk > heap_mapped) { unsigned long n = (new_brk - heap_mapped + PAGE_SIZE - 1) / PAGE_SIZE; - if ( n > nr_free_pages ) + if ( !chk_free_pages(n) ) { printk("Memory exhausted: want %ld pages, but only %ld are left\n", n, nr_free_pages); -- 2.6.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |