ia64/linux-2.6.18-xen.hg

view scripts/pnmtologo.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 /*
3 * Convert a logo in ASCII PNM format to C source suitable for inclusion in
4 * the Linux kernel
5 *
6 * (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org>
7 *
8 * --------------------------------------------------------------------------
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of the Linux
12 * distribution for more details.
13 */
15 #include <ctype.h>
16 #include <errno.h>
17 #include <stdarg.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
24 static const char *programname;
25 static const char *filename;
26 static const char *logoname = "linux_logo";
27 static const char *outputname;
28 static FILE *out;
31 #define LINUX_LOGO_MONO 1 /* monochrome black/white */
32 #define LINUX_LOGO_VGA16 2 /* 16 colors VGA text palette */
33 #define LINUX_LOGO_CLUT224 3 /* 224 colors */
34 #define LINUX_LOGO_GRAY256 4 /* 256 levels grayscale */
36 static const char *logo_types[LINUX_LOGO_GRAY256+1] = {
37 [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO",
38 [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16",
39 [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224",
40 [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256"
41 };
43 #define MAX_LINUX_LOGO_COLORS 224
45 struct color {
46 unsigned char red;
47 unsigned char green;
48 unsigned char blue;
49 };
51 static const struct color clut_vga16[16] = {
52 { 0x00, 0x00, 0x00 },
53 { 0x00, 0x00, 0xaa },
54 { 0x00, 0xaa, 0x00 },
55 { 0x00, 0xaa, 0xaa },
56 { 0xaa, 0x00, 0x00 },
57 { 0xaa, 0x00, 0xaa },
58 { 0xaa, 0x55, 0x00 },
59 { 0xaa, 0xaa, 0xaa },
60 { 0x55, 0x55, 0x55 },
61 { 0x55, 0x55, 0xff },
62 { 0x55, 0xff, 0x55 },
63 { 0x55, 0xff, 0xff },
64 { 0xff, 0x55, 0x55 },
65 { 0xff, 0x55, 0xff },
66 { 0xff, 0xff, 0x55 },
67 { 0xff, 0xff, 0xff },
68 };
71 static int logo_type = LINUX_LOGO_CLUT224;
72 static unsigned int logo_width;
73 static unsigned int logo_height;
74 static struct color **logo_data;
75 static struct color logo_clut[MAX_LINUX_LOGO_COLORS];
76 static unsigned int logo_clutsize;
78 static void die(const char *fmt, ...)
79 __attribute__ ((noreturn)) __attribute ((format (printf, 1, 2)));
80 static void usage(void) __attribute ((noreturn));
83 static unsigned int get_number(FILE *fp)
84 {
85 int c, val;
87 /* Skip leading whitespace */
88 do {
89 c = fgetc(fp);
90 if (c == EOF)
91 die("%s: end of file\n", filename);
92 if (c == '#') {
93 /* Ignore comments 'till end of line */
94 do {
95 c = fgetc(fp);
96 if (c == EOF)
97 die("%s: end of file\n", filename);
98 } while (c != '\n');
99 }
100 } while (isspace(c));
102 /* Parse decimal number */
103 val = 0;
104 while (isdigit(c)) {
105 val = 10*val+c-'0';
106 c = fgetc(fp);
107 if (c == EOF)
108 die("%s: end of file\n", filename);
109 }
110 return val;
111 }
113 static unsigned int get_number255(FILE *fp, unsigned int maxval)
114 {
115 unsigned int val = get_number(fp);
116 return (255*val+maxval/2)/maxval;
117 }
119 static void read_image(void)
120 {
121 FILE *fp;
122 unsigned int i, j;
123 int magic;
124 unsigned int maxval;
126 /* open image file */
127 fp = fopen(filename, "r");
128 if (!fp)
129 die("Cannot open file %s: %s\n", filename, strerror(errno));
131 /* check file type and read file header */
132 magic = fgetc(fp);
133 if (magic != 'P')
134 die("%s is not a PNM file\n", filename);
135 magic = fgetc(fp);
136 switch (magic) {
137 case '1':
138 case '2':
139 case '3':
140 /* Plain PBM/PGM/PPM */
141 break;
143 case '4':
144 case '5':
145 case '6':
146 /* Binary PBM/PGM/PPM */
147 die("%s: Binary PNM is not supported\n"
148 "Use pnmnoraw(1) to convert it to ASCII PNM\n", filename);
150 default:
151 die("%s is not a PNM file\n", filename);
152 }
153 logo_width = get_number(fp);
154 logo_height = get_number(fp);
156 /* allocate image data */
157 logo_data = (struct color **)malloc(logo_height*sizeof(struct color *));
158 if (!logo_data)
159 die("%s\n", strerror(errno));
160 for (i = 0; i < logo_height; i++) {
161 logo_data[i] = malloc(logo_width*sizeof(struct color));
162 if (!logo_data[i])
163 die("%s\n", strerror(errno));
164 }
166 /* read image data */
167 switch (magic) {
168 case '1':
169 /* Plain PBM */
170 for (i = 0; i < logo_height; i++)
171 for (j = 0; j < logo_width; j++)
172 logo_data[i][j].red = logo_data[i][j].green =
173 logo_data[i][j].blue = 255*(1-get_number(fp));
174 break;
176 case '2':
177 /* Plain PGM */
178 maxval = get_number(fp);
179 for (i = 0; i < logo_height; i++)
180 for (j = 0; j < logo_width; j++)
181 logo_data[i][j].red = logo_data[i][j].green =
182 logo_data[i][j].blue = get_number255(fp, maxval);
183 break;
185 case '3':
186 /* Plain PPM */
187 maxval = get_number(fp);
188 for (i = 0; i < logo_height; i++)
189 for (j = 0; j < logo_width; j++) {
190 logo_data[i][j].red = get_number255(fp, maxval);
191 logo_data[i][j].green = get_number255(fp, maxval);
192 logo_data[i][j].blue = get_number255(fp, maxval);
193 }
194 break;
195 }
197 /* close file */
198 fclose(fp);
199 }
201 static inline int is_black(struct color c)
202 {
203 return c.red == 0 && c.green == 0 && c.blue == 0;
204 }
206 static inline int is_white(struct color c)
207 {
208 return c.red == 255 && c.green == 255 && c.blue == 255;
209 }
211 static inline int is_gray(struct color c)
212 {
213 return c.red == c.green && c.red == c.blue;
214 }
216 static inline int is_equal(struct color c1, struct color c2)
217 {
218 return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue;
219 }
221 static void write_header(void)
222 {
223 /* open logo file */
224 if (outputname) {
225 out = fopen(outputname, "w");
226 if (!out)
227 die("Cannot create file %s: %s\n", outputname, strerror(errno));
228 } else {
229 out = stdout;
230 }
232 fputs("/*\n", out);
233 fputs(" * DO NOT EDIT THIS FILE!\n", out);
234 fputs(" *\n", out);
235 fprintf(out, " * It was automatically generated from %s\n", filename);
236 fputs(" *\n", out);
237 fprintf(out, " * Linux logo %s\n", logoname);
238 fputs(" */\n\n", out);
239 fputs("#include <linux/linux_logo.h>\n\n", out);
240 fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
241 logoname);
242 }
244 static void write_footer(void)
245 {
246 fputs("\n};\n\n", out);
247 fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
248 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
249 fprintf(out, " .width\t= %d,\n", logo_width);
250 fprintf(out, " .height\t= %d,\n", logo_height);
251 if (logo_type == LINUX_LOGO_CLUT224) {
252 fprintf(out, " .clutsize\t= %d,\n", logo_clutsize);
253 fprintf(out, " .clut\t= %s_clut,\n", logoname);
254 }
255 fprintf(out, " .data\t= %s_data\n", logoname);
256 fputs("};\n\n", out);
258 /* close logo file */
259 if (outputname)
260 fclose(out);
261 }
263 static int write_hex_cnt;
265 static void write_hex(unsigned char byte)
266 {
267 if (write_hex_cnt % 12)
268 fprintf(out, ", 0x%02x", byte);
269 else if (write_hex_cnt)
270 fprintf(out, ",\n\t0x%02x", byte);
271 else
272 fprintf(out, "\t0x%02x", byte);
273 write_hex_cnt++;
274 }
276 static void write_logo_mono(void)
277 {
278 unsigned int i, j;
279 unsigned char val, bit;
281 /* validate image */
282 for (i = 0; i < logo_height; i++)
283 for (j = 0; j < logo_width; j++)
284 if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))
285 die("Image must be monochrome\n");
287 /* write file header */
288 write_header();
290 /* write logo data */
291 for (i = 0; i < logo_height; i++) {
292 for (j = 0; j < logo_width;) {
293 for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1)
294 if (logo_data[i][j].red)
295 val |= bit;
296 write_hex(val);
297 }
298 }
300 /* write logo structure and file footer */
301 write_footer();
302 }
304 static void write_logo_vga16(void)
305 {
306 unsigned int i, j, k;
307 unsigned char val;
309 /* validate image */
310 for (i = 0; i < logo_height; i++)
311 for (j = 0; j < logo_width; j++) {
312 for (k = 0; k < 16; k++)
313 if (is_equal(logo_data[i][j], clut_vga16[k]))
314 break;
315 if (k == 16)
316 die("Image must use the 16 console colors only\n"
317 "Use ppmquant(1) -map clut_vga16.ppm to reduce the number "
318 "of colors\n");
319 }
321 /* write file header */
322 write_header();
324 /* write logo data */
325 for (i = 0; i < logo_height; i++)
326 for (j = 0; j < logo_width; j++) {
327 for (k = 0; k < 16; k++)
328 if (is_equal(logo_data[i][j], clut_vga16[k]))
329 break;
330 val = k<<4;
331 if (++j < logo_width) {
332 for (k = 0; k < 16; k++)
333 if (is_equal(logo_data[i][j], clut_vga16[k]))
334 break;
335 val |= k;
336 }
337 write_hex(val);
338 }
340 /* write logo structure and file footer */
341 write_footer();
342 }
344 static void write_logo_clut224(void)
345 {
346 unsigned int i, j, k;
348 /* validate image */
349 for (i = 0; i < logo_height; i++)
350 for (j = 0; j < logo_width; j++) {
351 for (k = 0; k < logo_clutsize; k++)
352 if (is_equal(logo_data[i][j], logo_clut[k]))
353 break;
354 if (k == logo_clutsize) {
355 if (logo_clutsize == MAX_LINUX_LOGO_COLORS)
356 die("Image has more than %d colors\n"
357 "Use ppmquant(1) to reduce the number of colors\n",
358 MAX_LINUX_LOGO_COLORS);
359 logo_clut[logo_clutsize++] = logo_data[i][j];
360 }
361 }
363 /* write file header */
364 write_header();
366 /* write logo data */
367 for (i = 0; i < logo_height; i++)
368 for (j = 0; j < logo_width; j++) {
369 for (k = 0; k < logo_clutsize; k++)
370 if (is_equal(logo_data[i][j], logo_clut[k]))
371 break;
372 write_hex(k+32);
373 }
374 fputs("\n};\n\n", out);
376 /* write logo clut */
377 fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
378 logoname);
379 write_hex_cnt = 0;
380 for (i = 0; i < logo_clutsize; i++) {
381 write_hex(logo_clut[i].red);
382 write_hex(logo_clut[i].green);
383 write_hex(logo_clut[i].blue);
384 }
386 /* write logo structure and file footer */
387 write_footer();
388 }
390 static void write_logo_gray256(void)
391 {
392 unsigned int i, j;
394 /* validate image */
395 for (i = 0; i < logo_height; i++)
396 for (j = 0; j < logo_width; j++)
397 if (!is_gray(logo_data[i][j]))
398 die("Image must be grayscale\n");
400 /* write file header */
401 write_header();
403 /* write logo data */
404 for (i = 0; i < logo_height; i++)
405 for (j = 0; j < logo_width; j++)
406 write_hex(logo_data[i][j].red);
408 /* write logo structure and file footer */
409 write_footer();
410 }
412 static void die(const char *fmt, ...)
413 {
414 va_list ap;
416 va_start(ap, fmt);
417 vfprintf(stderr, fmt, ap);
418 va_end(ap);
420 exit(1);
421 }
423 static void usage(void)
424 {
425 die("\n"
426 "Usage: %s [options] <filename>\n"
427 "\n"
428 "Valid options:\n"
429 " -h : display this usage information\n"
430 " -n <name> : specify logo name (default: linux_logo)\n"
431 " -o <output> : output to file <output> instead of stdout\n"
432 " -t <type> : specify logo type, one of\n"
433 " mono : monochrome black/white\n"
434 " vga16 : 16 colors VGA text palette\n"
435 " clut224 : 224 colors (default)\n"
436 " gray256 : 256 levels grayscale\n"
437 "\n", programname);
438 }
440 int main(int argc, char *argv[])
441 {
442 int opt;
444 programname = argv[0];
446 opterr = 0;
447 while (1) {
448 opt = getopt(argc, argv, "hn:o:t:");
449 if (opt == -1)
450 break;
452 switch (opt) {
453 case 'h':
454 usage();
455 break;
457 case 'n':
458 logoname = optarg;
459 break;
461 case 'o':
462 outputname = optarg;
463 break;
465 case 't':
466 if (!strcmp(optarg, "mono"))
467 logo_type = LINUX_LOGO_MONO;
468 else if (!strcmp(optarg, "vga16"))
469 logo_type = LINUX_LOGO_VGA16;
470 else if (!strcmp(optarg, "clut224"))
471 logo_type = LINUX_LOGO_CLUT224;
472 else if (!strcmp(optarg, "gray256"))
473 logo_type = LINUX_LOGO_GRAY256;
474 else
475 usage();
476 break;
478 default:
479 usage();
480 break;
481 }
482 }
483 if (optind != argc-1)
484 usage();
486 filename = argv[optind];
488 read_image();
489 switch (logo_type) {
490 case LINUX_LOGO_MONO:
491 write_logo_mono();
492 break;
494 case LINUX_LOGO_VGA16:
495 write_logo_vga16();
496 break;
498 case LINUX_LOGO_CLUT224:
499 write_logo_clut224();
500 break;
502 case LINUX_LOGO_GRAY256:
503 write_logo_gray256();
504 break;
505 }
506 exit(0);
507 }