ia64/linux-2.6.18-xen.hg

view arch/alpha/boot/misc.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 * misc.c
3 *
4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux.
6 *
7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8 *
9 * Modified for ARM Linux by Russell King
10 *
11 * Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
12 * For this code to run directly from Flash, all constant variables must
13 * be marked with 'const' and all other variables initialized at run-time
14 * only. This way all non constant variables will end up in the bss segment,
15 * which should point to addresses in RAM and cleared to 0 on start.
16 * This allows for a much quicker boot time.
17 *
18 * Modified for Alpha, from the ARM version, by Jay Estabrook 2003.
19 */
21 #include <linux/kernel.h>
23 #include <asm/uaccess.h>
25 #define memzero(s,n) memset ((s),0,(n))
26 #define puts srm_printk
27 extern long srm_printk(const char *, ...)
28 __attribute__ ((format (printf, 1, 2)));
30 /*
31 * gzip delarations
32 */
33 #define OF(args) args
34 #define STATIC static
36 typedef unsigned char uch;
37 typedef unsigned short ush;
38 typedef unsigned long ulg;
40 #define WSIZE 0x8000 /* Window size must be at least 32k, */
41 /* and a power of two */
43 static uch *inbuf; /* input buffer */
44 static uch *window; /* Sliding window buffer */
46 static unsigned insize; /* valid bytes in inbuf */
47 static unsigned inptr; /* index of next byte to be processed in inbuf */
48 static unsigned outcnt; /* bytes in output buffer */
50 /* gzip flag byte */
51 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
52 #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
53 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
54 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
55 #define COMMENT 0x10 /* bit 4 set: file comment present */
56 #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
57 #define RESERVED 0xC0 /* bit 6,7: reserved */
59 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
61 /* Diagnostic functions */
62 #ifdef DEBUG
63 # define Assert(cond,msg) {if(!(cond)) error(msg);}
64 # define Trace(x) fprintf x
65 # define Tracev(x) {if (verbose) fprintf x ;}
66 # define Tracevv(x) {if (verbose>1) fprintf x ;}
67 # define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
68 # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
69 #else
70 # define Assert(cond,msg)
71 # define Trace(x)
72 # define Tracev(x)
73 # define Tracevv(x)
74 # define Tracec(c,x)
75 # define Tracecv(c,x)
76 #endif
78 static int fill_inbuf(void);
79 static void flush_window(void);
80 static void error(char *m);
81 static void gzip_mark(void **);
82 static void gzip_release(void **);
84 static char *input_data;
85 static int input_data_size;
87 static uch *output_data;
88 static ulg output_ptr;
89 static ulg bytes_out;
91 static void *malloc(int size);
92 static void free(void *where);
93 static void error(char *m);
94 static void gzip_mark(void **);
95 static void gzip_release(void **);
97 extern int end;
98 static ulg free_mem_ptr;
99 static ulg free_mem_ptr_end;
101 #define HEAP_SIZE 0x2000
103 #include "../../../lib/inflate.c"
105 static void *malloc(int size)
106 {
107 void *p;
109 if (size <0) error("Malloc error");
110 if (free_mem_ptr <= 0) error("Memory error");
112 free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
114 p = (void *)free_mem_ptr;
115 free_mem_ptr += size;
117 if (free_mem_ptr >= free_mem_ptr_end)
118 error("Out of memory");
119 return p;
120 }
122 static void free(void *where)
123 { /* gzip_mark & gzip_release do the free */
124 }
126 static void gzip_mark(void **ptr)
127 {
128 *ptr = (void *) free_mem_ptr;
129 }
131 static void gzip_release(void **ptr)
132 {
133 free_mem_ptr = (long) *ptr;
134 }
136 /* ===========================================================================
137 * Fill the input buffer. This is called only when the buffer is empty
138 * and at least one byte is really needed.
139 */
140 int fill_inbuf(void)
141 {
142 if (insize != 0)
143 error("ran out of input data");
145 inbuf = input_data;
146 insize = input_data_size;
148 inptr = 1;
149 return inbuf[0];
150 }
152 /* ===========================================================================
153 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
154 * (Used for the decompressed data only.)
155 */
156 void flush_window(void)
157 {
158 ulg c = crc;
159 unsigned n;
160 uch *in, *out, ch;
162 in = window;
163 out = &output_data[output_ptr];
164 for (n = 0; n < outcnt; n++) {
165 ch = *out++ = *in++;
166 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
167 }
168 crc = c;
169 bytes_out += (ulg)outcnt;
170 output_ptr += (ulg)outcnt;
171 outcnt = 0;
172 /* puts("."); */
173 }
175 static void error(char *x)
176 {
177 puts("\n\n");
178 puts(x);
179 puts("\n\n -- System halted");
181 while(1); /* Halt */
182 }
184 unsigned int
185 decompress_kernel(void *output_start,
186 void *input_start,
187 size_t ksize,
188 size_t kzsize)
189 {
190 output_data = (uch *)output_start;
191 input_data = (uch *)input_start;
192 input_data_size = kzsize; /* use compressed size */
194 /* FIXME FIXME FIXME */
195 free_mem_ptr = (ulg)output_start + ksize;
196 free_mem_ptr_end = (ulg)output_start + ksize + 0x200000;
197 /* FIXME FIXME FIXME */
199 /* put in temp area to reduce initial footprint */
200 window = malloc(WSIZE);
202 makecrc();
203 /* puts("Uncompressing Linux..."); */
204 gunzip();
205 /* puts(" done, booting the kernel.\n"); */
206 return output_ptr;
207 }