ia64/linux-2.6.18-xen.hg

view arch/mips/sni/sniprom.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * Big Endian PROM code for SNI RM machines
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
9 * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
10 */
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/string.h>
16 #include <asm/addrspace.h>
17 #include <asm/sni.h>
18 #include <asm/mipsprom.h>
19 #include <asm/bootinfo.h>
21 /* special SNI prom calls */
22 /*
23 * This does not exist in all proms - SINIX compares
24 * the prom env variable "version" against "2.0008"
25 * or greater. If lesser it tries to probe interesting
26 * registers
27 */
28 #define PROM_GET_MEMCONF 58
30 #define PROM_VEC (u64 *)CKSEG1ADDR(0x1fc00000)
31 #define PROM_ENTRY(x) (PROM_VEC + (x))
34 #undef DEBUG
35 #ifdef DEBUG
36 #define DBG_PRINTF(x...) prom_printf(x)
37 #else
38 #define DBG_PRINTF(x...)
39 #endif
41 static int *(*__prom_putchar)(int) = (int *(*)(int))PROM_ENTRY(PROM_PUTCHAR);
42 static char *(*__prom_getenv)(char *) = (char *(*)(char *))PROM_ENTRY(PROM_GETENV);
43 static void (*__prom_get_memconf)(void *) = (void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF);
45 char *prom_getenv (char *s)
46 {
47 return __prom_getenv(s);
48 }
50 void prom_printf(char *fmt, ...)
51 {
52 va_list args;
53 char ppbuf[1024];
54 char *bptr;
56 va_start(args, fmt);
57 vsprintf(ppbuf, fmt, args);
59 bptr = ppbuf;
61 while (*bptr != 0) {
62 if (*bptr == '\n')
63 __prom_putchar('\r');
65 __prom_putchar(*bptr++);
66 }
67 va_end(args);
68 }
70 unsigned long prom_free_prom_memory(void)
71 {
72 return 0;
73 }
75 /*
76 * /proc/cpuinfo system type
77 *
78 */
79 static const char *systype = "Unknown";
80 const char *get_system_type(void)
81 {
82 return systype;
83 }
85 #define SNI_IDPROM_BASE 0xbff00000
86 #define SNI_IDPROM_MEMSIZE (SNI_IDPROM_BASE+0x28) /* Memsize in 16MB quantities */
87 #define SNI_IDPROM_BRDTYPE (SNI_IDPROM_BASE+0x29) /* Board Type */
88 #define SNI_IDPROM_CPUTYPE (SNI_IDPROM_BASE+0x30) /* CPU Type */
90 #define SNI_IDPROM_SIZE 0x1000
92 #ifdef DEBUG
93 static void sni_idprom_dump(void)
94 {
95 int i;
97 prom_printf("SNI IDProm dump (first 128byte):\n");
98 for(i=0;i<128;i++) {
99 if (i%16 == 0)
100 prom_printf("%04x ", i);
102 prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE+i));
104 if (i%16 == 15)
105 prom_printf("\n");
106 }
107 }
108 #endif
110 static void sni_mem_init(void )
111 {
112 int i, memsize;
113 struct membank {
114 u32 size;
115 u32 base;
116 u32 size2;
117 u32 pad1;
118 u32 pad2;
119 } memconf[8];
121 /* MemSIZE from prom in 16MByte chunks */
122 memsize=*((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
124 DBG_PRINTF("IDProm memsize: %lu MByte\n", memsize);
126 /* get memory bank layout from prom */
127 __prom_get_memconf(&memconf);
129 DBG_PRINTF("prom_get_mem_conf memory configuration:\n");
130 for(i=0;i<8 && memconf[i].size;i++) {
131 prom_printf("Bank%d: %08x @ %08x\n", i,
132 memconf[i].size, memconf[i].base);
133 add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
134 }
135 }
137 void __init prom_init(void)
138 {
139 int argc = fw_arg0;
140 char **argv = (void *)fw_arg1;
141 unsigned int sni_brd_type = *(unsigned char *) SNI_IDPROM_BRDTYPE;
142 int i;
144 DBG_PRINTF("Found SNI brdtype %02x\n", sni_brd_type);
146 #ifdef DEBUG
147 sni_idprom_dump();
148 #endif
149 sni_mem_init();
151 /* copy prom cmdline parameters to kernel cmdline */
152 for (i = 1; i < argc; i++) {
153 strcat(arcs_cmdline, argv[i]);
154 if (i < (argc - 1))
155 strcat(arcs_cmdline, " ");
156 }
157 }