ia64/linux-2.6.18-xen.hg

view init/do_mounts_rd.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
2 #include <linux/kernel.h>
3 #include <linux/fs.h>
4 #include <linux/minix_fs.h>
5 #include <linux/ext2_fs.h>
6 #include <linux/romfs_fs.h>
7 #include <linux/cramfs_fs.h>
8 #include <linux/initrd.h>
9 #include <linux/string.h>
11 #include "do_mounts.h"
13 #define BUILD_CRAMDISK
15 int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
17 static int __init prompt_ramdisk(char *str)
18 {
19 rd_prompt = simple_strtol(str,NULL,0) & 1;
20 return 1;
21 }
22 __setup("prompt_ramdisk=", prompt_ramdisk);
24 int __initdata rd_image_start; /* starting block # of image */
26 static int __init ramdisk_start_setup(char *str)
27 {
28 rd_image_start = simple_strtol(str,NULL,0);
29 return 1;
30 }
31 __setup("ramdisk_start=", ramdisk_start_setup);
33 static int __init crd_load(int in_fd, int out_fd);
35 /*
36 * This routine tries to find a RAM disk image to load, and returns the
37 * number of blocks to read for a non-compressed image, 0 if the image
38 * is a compressed image, and -1 if an image with the right magic
39 * numbers could not be found.
40 *
41 * We currently check for the following magic numbers:
42 * minix
43 * ext2
44 * romfs
45 * cramfs
46 * gzip
47 */
48 static int __init
49 identify_ramdisk_image(int fd, int start_block)
50 {
51 const int size = 512;
52 struct minix_super_block *minixsb;
53 struct ext2_super_block *ext2sb;
54 struct romfs_super_block *romfsb;
55 struct cramfs_super *cramfsb;
56 int nblocks = -1;
57 unsigned char *buf;
59 buf = kmalloc(size, GFP_KERNEL);
60 if (buf == 0)
61 return -1;
63 minixsb = (struct minix_super_block *) buf;
64 ext2sb = (struct ext2_super_block *) buf;
65 romfsb = (struct romfs_super_block *) buf;
66 cramfsb = (struct cramfs_super *) buf;
67 memset(buf, 0xe5, size);
69 /*
70 * Read block 0 to test for gzipped kernel
71 */
72 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
73 sys_read(fd, buf, size);
75 /*
76 * If it matches the gzip magic numbers, return -1
77 */
78 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
79 printk(KERN_NOTICE
80 "RAMDISK: Compressed image found at block %d\n",
81 start_block);
82 nblocks = 0;
83 goto done;
84 }
86 /* romfs is at block zero too */
87 if (romfsb->word0 == ROMSB_WORD0 &&
88 romfsb->word1 == ROMSB_WORD1) {
89 printk(KERN_NOTICE
90 "RAMDISK: romfs filesystem found at block %d\n",
91 start_block);
92 nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
93 goto done;
94 }
96 if (cramfsb->magic == CRAMFS_MAGIC) {
97 printk(KERN_NOTICE
98 "RAMDISK: cramfs filesystem found at block %d\n",
99 start_block);
100 nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
101 goto done;
102 }
104 /*
105 * Read block 1 to test for minix and ext2 superblock
106 */
107 sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
108 sys_read(fd, buf, size);
110 /* Try minix */
111 if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
112 minixsb->s_magic == MINIX_SUPER_MAGIC2) {
113 printk(KERN_NOTICE
114 "RAMDISK: Minix filesystem found at block %d\n",
115 start_block);
116 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
117 goto done;
118 }
120 /* Try ext2 */
121 if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
122 printk(KERN_NOTICE
123 "RAMDISK: ext2 filesystem found at block %d\n",
124 start_block);
125 nblocks = le32_to_cpu(ext2sb->s_blocks_count) <<
126 le32_to_cpu(ext2sb->s_log_block_size);
127 goto done;
128 }
130 printk(KERN_NOTICE
131 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
132 start_block);
134 done:
135 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
136 kfree(buf);
137 return nblocks;
138 }
140 int __init rd_load_image(char *from)
141 {
142 int res = 0;
143 int in_fd, out_fd;
144 unsigned long rd_blocks, devblocks;
145 int nblocks, i, disk;
146 char *buf = NULL;
147 unsigned short rotate = 0;
148 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
149 char rotator[4] = { '|' , '/' , '-' , '\\' };
150 #endif
152 out_fd = sys_open("/dev/ram", O_RDWR, 0);
153 if (out_fd < 0)
154 goto out;
156 in_fd = sys_open(from, O_RDONLY, 0);
157 if (in_fd < 0)
158 goto noclose_input;
160 nblocks = identify_ramdisk_image(in_fd, rd_image_start);
161 if (nblocks < 0)
162 goto done;
164 if (nblocks == 0) {
165 #ifdef BUILD_CRAMDISK
166 if (crd_load(in_fd, out_fd) == 0)
167 goto successful_load;
168 #else
169 printk(KERN_NOTICE
170 "RAMDISK: Kernel does not support compressed "
171 "RAM disk images\n");
172 #endif
173 goto done;
174 }
176 /*
177 * NOTE NOTE: nblocks is not actually blocks but
178 * the number of kibibytes of data to load into a ramdisk.
179 * So any ramdisk block size that is a multiple of 1KiB should
180 * work when the appropriate ramdisk_blocksize is specified
181 * on the command line.
182 *
183 * The default ramdisk_blocksize is 1KiB and it is generally
184 * silly to use anything else, so make sure to use 1KiB
185 * blocksize while generating ext2fs ramdisk-images.
186 */
187 if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
188 rd_blocks = 0;
189 else
190 rd_blocks >>= 1;
192 if (nblocks > rd_blocks) {
193 printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n",
194 nblocks, rd_blocks);
195 goto done;
196 }
198 /*
199 * OK, time to copy in the data
200 */
201 if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
202 devblocks = 0;
203 else
204 devblocks >>= 1;
206 if (strcmp(from, "/initrd.image") == 0)
207 devblocks = nblocks;
209 if (devblocks == 0) {
210 printk(KERN_ERR "RAMDISK: could not determine device size\n");
211 goto done;
212 }
214 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
215 if (buf == 0) {
216 printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
217 goto done;
218 }
220 printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
221 nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
222 for (i = 0, disk = 1; i < nblocks; i++) {
223 if (i && (i % devblocks == 0)) {
224 printk("done disk #%d.\n", disk++);
225 rotate = 0;
226 if (sys_close(in_fd)) {
227 printk("Error closing the disk.\n");
228 goto noclose_input;
229 }
230 change_floppy("disk #%d", disk);
231 in_fd = sys_open(from, O_RDONLY, 0);
232 if (in_fd < 0) {
233 printk("Error opening disk.\n");
234 goto noclose_input;
235 }
236 printk("Loading disk #%d... ", disk);
237 }
238 sys_read(in_fd, buf, BLOCK_SIZE);
239 sys_write(out_fd, buf, BLOCK_SIZE);
240 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
241 if (!(i % 16)) {
242 printk("%c\b", rotator[rotate & 0x3]);
243 rotate++;
244 }
245 #endif
246 }
247 printk("done.\n");
249 successful_load:
250 res = 1;
251 done:
252 sys_close(in_fd);
253 noclose_input:
254 sys_close(out_fd);
255 out:
256 kfree(buf);
257 sys_unlink("/dev/ram");
258 return res;
259 }
261 int __init rd_load_disk(int n)
262 {
263 if (rd_prompt)
264 change_floppy("root floppy disk to be loaded into RAM disk");
265 create_dev("/dev/root", ROOT_DEV);
266 create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
267 return rd_load_image("/dev/root");
268 }
270 #ifdef BUILD_CRAMDISK
272 /*
273 * gzip declarations
274 */
276 #define OF(args) args
278 #ifndef memzero
279 #define memzero(s, n) memset ((s), 0, (n))
280 #endif
282 typedef unsigned char uch;
283 typedef unsigned short ush;
284 typedef unsigned long ulg;
286 #define INBUFSIZ 4096
287 #define WSIZE 0x8000 /* window size--must be a power of two, and */
288 /* at least 32K for zip's deflate method */
290 static uch *inbuf;
291 static uch *window;
293 static unsigned insize; /* valid bytes in inbuf */
294 static unsigned inptr; /* index of next byte to be processed in inbuf */
295 static unsigned outcnt; /* bytes in output buffer */
296 static int exit_code;
297 static int unzip_error;
298 static long bytes_out;
299 static int crd_infd, crd_outfd;
301 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
303 /* Diagnostic functions (stubbed out) */
304 #define Assert(cond,msg)
305 #define Trace(x)
306 #define Tracev(x)
307 #define Tracevv(x)
308 #define Tracec(c,x)
309 #define Tracecv(c,x)
311 #define STATIC static
312 #define INIT __init
314 static int __init fill_inbuf(void);
315 static void __init flush_window(void);
316 static void __init *malloc(size_t size);
317 static void __init free(void *where);
318 static void __init error(char *m);
319 static void __init gzip_mark(void **);
320 static void __init gzip_release(void **);
322 #include "../lib/inflate.c"
324 static void __init *malloc(size_t size)
325 {
326 return kmalloc(size, GFP_KERNEL);
327 }
329 static void __init free(void *where)
330 {
331 kfree(where);
332 }
334 static void __init gzip_mark(void **ptr)
335 {
336 }
338 static void __init gzip_release(void **ptr)
339 {
340 }
343 /* ===========================================================================
344 * Fill the input buffer. This is called only when the buffer is empty
345 * and at least one byte is really needed.
346 * Returning -1 does not guarantee that gunzip() will ever return.
347 */
348 static int __init fill_inbuf(void)
349 {
350 if (exit_code) return -1;
352 insize = sys_read(crd_infd, inbuf, INBUFSIZ);
353 if (insize == 0) {
354 error("RAMDISK: ran out of compressed data");
355 return -1;
356 }
358 inptr = 1;
360 return inbuf[0];
361 }
363 /* ===========================================================================
364 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
365 * (Used for the decompressed data only.)
366 */
367 static void __init flush_window(void)
368 {
369 ulg c = crc; /* temporary variable */
370 unsigned n, written;
371 uch *in, ch;
373 written = sys_write(crd_outfd, window, outcnt);
374 if (written != outcnt && unzip_error == 0) {
375 printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
376 written, outcnt, bytes_out);
377 unzip_error = 1;
378 }
379 in = window;
380 for (n = 0; n < outcnt; n++) {
381 ch = *in++;
382 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
383 }
384 crc = c;
385 bytes_out += (ulg)outcnt;
386 outcnt = 0;
387 }
389 static void __init error(char *x)
390 {
391 printk(KERN_ERR "%s\n", x);
392 exit_code = 1;
393 unzip_error = 1;
394 }
396 static int __init crd_load(int in_fd, int out_fd)
397 {
398 int result;
400 insize = 0; /* valid bytes in inbuf */
401 inptr = 0; /* index of next byte to be processed in inbuf */
402 outcnt = 0; /* bytes in output buffer */
403 exit_code = 0;
404 bytes_out = 0;
405 crc = (ulg)0xffffffffL; /* shift register contents */
407 crd_infd = in_fd;
408 crd_outfd = out_fd;
409 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
410 if (inbuf == 0) {
411 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
412 return -1;
413 }
414 window = kmalloc(WSIZE, GFP_KERNEL);
415 if (window == 0) {
416 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
417 kfree(inbuf);
418 return -1;
419 }
420 makecrc();
421 result = gunzip();
422 if (unzip_error)
423 result = 1;
424 kfree(inbuf);
425 kfree(window);
426 return result;
427 }
429 #endif /* BUILD_CRAMDISK */