ia64/linux-2.6.18-xen.hg

view scripts/kconfig/conf.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 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
6 #include <ctype.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <time.h>
12 #include <sys/stat.h>
14 #define LKC_DIRECT_LINK
15 #include "lkc.h"
17 static void conf(struct menu *menu);
18 static void check_conf(struct menu *menu);
20 enum {
21 ask_all,
22 ask_new,
23 ask_silent,
24 set_default,
25 set_yes,
26 set_mod,
27 set_no,
28 set_random
29 } input_mode = ask_all;
30 char *defconfig_file;
32 static int indent = 1;
33 static int valid_stdin = 1;
34 static int conf_cnt;
35 static char line[128];
36 static struct menu *rootEntry;
38 static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
40 static void strip(char *str)
41 {
42 char *p = str;
43 int l;
45 while ((isspace(*p)))
46 p++;
47 l = strlen(p);
48 if (p != str)
49 memmove(str, p, l + 1);
50 if (!l)
51 return;
52 p = str + l - 1;
53 while ((isspace(*p)))
54 *p-- = 0;
55 }
57 static void check_stdin(void)
58 {
59 if (!valid_stdin && input_mode == ask_silent) {
60 printf(_("aborted!\n\n"));
61 printf(_("Console input/output is redirected. "));
62 printf(_("Run 'make oldconfig' to update configuration.\n\n"));
63 exit(1);
64 }
65 }
67 static void conf_askvalue(struct symbol *sym, const char *def)
68 {
69 enum symbol_type type = sym_get_type(sym);
70 tristate val;
72 if (!sym_has_value(sym))
73 printf("(NEW) ");
75 line[0] = '\n';
76 line[1] = 0;
78 if (!sym_is_changable(sym)) {
79 printf("%s\n", def);
80 line[0] = '\n';
81 line[1] = 0;
82 return;
83 }
85 switch (input_mode) {
86 case set_no:
87 case set_mod:
88 case set_yes:
89 case set_random:
90 if (sym_has_value(sym)) {
91 printf("%s\n", def);
92 return;
93 }
94 break;
95 case ask_new:
96 case ask_silent:
97 if (sym_has_value(sym)) {
98 printf("%s\n", def);
99 return;
100 }
101 check_stdin();
102 case ask_all:
103 fflush(stdout);
104 fgets(line, 128, stdin);
105 return;
106 case set_default:
107 printf("%s\n", def);
108 return;
109 default:
110 break;
111 }
113 switch (type) {
114 case S_INT:
115 case S_HEX:
116 case S_STRING:
117 printf("%s\n", def);
118 return;
119 default:
120 ;
121 }
122 switch (input_mode) {
123 case set_yes:
124 if (sym_tristate_within_range(sym, yes)) {
125 line[0] = 'y';
126 line[1] = '\n';
127 line[2] = 0;
128 break;
129 }
130 case set_mod:
131 if (type == S_TRISTATE) {
132 if (sym_tristate_within_range(sym, mod)) {
133 line[0] = 'm';
134 line[1] = '\n';
135 line[2] = 0;
136 break;
137 }
138 } else {
139 if (sym_tristate_within_range(sym, yes)) {
140 line[0] = 'y';
141 line[1] = '\n';
142 line[2] = 0;
143 break;
144 }
145 }
146 case set_no:
147 if (sym_tristate_within_range(sym, no)) {
148 line[0] = 'n';
149 line[1] = '\n';
150 line[2] = 0;
151 break;
152 }
153 case set_random:
154 do {
155 val = (tristate)(random() % 3);
156 } while (!sym_tristate_within_range(sym, val));
157 switch (val) {
158 case no: line[0] = 'n'; break;
159 case mod: line[0] = 'm'; break;
160 case yes: line[0] = 'y'; break;
161 }
162 line[1] = '\n';
163 line[2] = 0;
164 break;
165 default:
166 break;
167 }
168 printf("%s", line);
169 }
171 int conf_string(struct menu *menu)
172 {
173 struct symbol *sym = menu->sym;
174 const char *def, *help;
176 while (1) {
177 printf("%*s%s ", indent - 1, "", menu->prompt->text);
178 printf("(%s) ", sym->name);
179 def = sym_get_string_value(sym);
180 if (sym_get_string_value(sym))
181 printf("[%s] ", def);
182 conf_askvalue(sym, def);
183 switch (line[0]) {
184 case '\n':
185 break;
186 case '?':
187 /* print help */
188 if (line[1] == '\n') {
189 help = nohelp_text;
190 if (menu->sym->help)
191 help = menu->sym->help;
192 printf("\n%s\n", menu->sym->help);
193 def = NULL;
194 break;
195 }
196 default:
197 line[strlen(line)-1] = 0;
198 def = line;
199 }
200 if (def && sym_set_string_value(sym, def))
201 return 0;
202 }
203 }
205 static int conf_sym(struct menu *menu)
206 {
207 struct symbol *sym = menu->sym;
208 int type;
209 tristate oldval, newval;
210 const char *help;
212 while (1) {
213 printf("%*s%s ", indent - 1, "", menu->prompt->text);
214 if (sym->name)
215 printf("(%s) ", sym->name);
216 type = sym_get_type(sym);
217 putchar('[');
218 oldval = sym_get_tristate_value(sym);
219 switch (oldval) {
220 case no:
221 putchar('N');
222 break;
223 case mod:
224 putchar('M');
225 break;
226 case yes:
227 putchar('Y');
228 break;
229 }
230 if (oldval != no && sym_tristate_within_range(sym, no))
231 printf("/n");
232 if (oldval != mod && sym_tristate_within_range(sym, mod))
233 printf("/m");
234 if (oldval != yes && sym_tristate_within_range(sym, yes))
235 printf("/y");
236 if (sym->help)
237 printf("/?");
238 printf("] ");
239 conf_askvalue(sym, sym_get_string_value(sym));
240 strip(line);
242 switch (line[0]) {
243 case 'n':
244 case 'N':
245 newval = no;
246 if (!line[1] || !strcmp(&line[1], "o"))
247 break;
248 continue;
249 case 'm':
250 case 'M':
251 newval = mod;
252 if (!line[1])
253 break;
254 continue;
255 case 'y':
256 case 'Y':
257 newval = yes;
258 if (!line[1] || !strcmp(&line[1], "es"))
259 break;
260 continue;
261 case 0:
262 newval = oldval;
263 break;
264 case '?':
265 goto help;
266 default:
267 continue;
268 }
269 if (sym_set_tristate_value(sym, newval))
270 return 0;
271 help:
272 help = nohelp_text;
273 if (sym->help)
274 help = sym->help;
275 printf("\n%s\n", help);
276 }
277 }
279 static int conf_choice(struct menu *menu)
280 {
281 struct symbol *sym, *def_sym;
282 struct menu *child;
283 int type;
284 bool is_new;
286 sym = menu->sym;
287 type = sym_get_type(sym);
288 is_new = !sym_has_value(sym);
289 if (sym_is_changable(sym)) {
290 conf_sym(menu);
291 sym_calc_value(sym);
292 switch (sym_get_tristate_value(sym)) {
293 case no:
294 return 1;
295 case mod:
296 return 0;
297 case yes:
298 break;
299 }
300 } else {
301 switch (sym_get_tristate_value(sym)) {
302 case no:
303 return 1;
304 case mod:
305 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
306 return 0;
307 case yes:
308 break;
309 }
310 }
312 while (1) {
313 int cnt, def;
315 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
316 def_sym = sym_get_choice_value(sym);
317 cnt = def = 0;
318 line[0] = 0;
319 for (child = menu->list; child; child = child->next) {
320 if (!menu_is_visible(child))
321 continue;
322 if (!child->sym) {
323 printf("%*c %s\n", indent, '*', menu_get_prompt(child));
324 continue;
325 }
326 cnt++;
327 if (child->sym == def_sym) {
328 def = cnt;
329 printf("%*c", indent, '>');
330 } else
331 printf("%*c", indent, ' ');
332 printf(" %d. %s", cnt, menu_get_prompt(child));
333 if (child->sym->name)
334 printf(" (%s)", child->sym->name);
335 if (!sym_has_value(child->sym))
336 printf(" (NEW)");
337 printf("\n");
338 }
339 printf("%*schoice", indent - 1, "");
340 if (cnt == 1) {
341 printf("[1]: 1\n");
342 goto conf_childs;
343 }
344 printf("[1-%d", cnt);
345 if (sym->help)
346 printf("?");
347 printf("]: ");
348 switch (input_mode) {
349 case ask_new:
350 case ask_silent:
351 if (!is_new) {
352 cnt = def;
353 printf("%d\n", cnt);
354 break;
355 }
356 check_stdin();
357 case ask_all:
358 fflush(stdout);
359 fgets(line, 128, stdin);
360 strip(line);
361 if (line[0] == '?') {
362 printf("\n%s\n", menu->sym->help ?
363 menu->sym->help : nohelp_text);
364 continue;
365 }
366 if (!line[0])
367 cnt = def;
368 else if (isdigit(line[0]))
369 cnt = atoi(line);
370 else
371 continue;
372 break;
373 case set_random:
374 def = (random() % cnt) + 1;
375 case set_default:
376 case set_yes:
377 case set_mod:
378 case set_no:
379 cnt = def;
380 printf("%d\n", cnt);
381 break;
382 }
384 conf_childs:
385 for (child = menu->list; child; child = child->next) {
386 if (!child->sym || !menu_is_visible(child))
387 continue;
388 if (!--cnt)
389 break;
390 }
391 if (!child)
392 continue;
393 if (line[strlen(line) - 1] == '?') {
394 printf("\n%s\n", child->sym->help ?
395 child->sym->help : nohelp_text);
396 continue;
397 }
398 sym_set_choice_value(sym, child->sym);
399 if (child->list) {
400 indent += 2;
401 conf(child->list);
402 indent -= 2;
403 }
404 return 1;
405 }
406 }
408 static void conf(struct menu *menu)
409 {
410 struct symbol *sym;
411 struct property *prop;
412 struct menu *child;
414 if (!menu_is_visible(menu))
415 return;
417 sym = menu->sym;
418 prop = menu->prompt;
419 if (prop) {
420 const char *prompt;
422 switch (prop->type) {
423 case P_MENU:
424 if (input_mode == ask_silent && rootEntry != menu) {
425 check_conf(menu);
426 return;
427 }
428 case P_COMMENT:
429 prompt = menu_get_prompt(menu);
430 if (prompt)
431 printf("%*c\n%*c %s\n%*c\n",
432 indent, '*',
433 indent, '*', prompt,
434 indent, '*');
435 default:
436 ;
437 }
438 }
440 if (!sym)
441 goto conf_childs;
443 if (sym_is_choice(sym)) {
444 conf_choice(menu);
445 if (sym->curr.tri != mod)
446 return;
447 goto conf_childs;
448 }
450 switch (sym->type) {
451 case S_INT:
452 case S_HEX:
453 case S_STRING:
454 conf_string(menu);
455 break;
456 default:
457 conf_sym(menu);
458 break;
459 }
461 conf_childs:
462 if (sym)
463 indent += 2;
464 for (child = menu->list; child; child = child->next)
465 conf(child);
466 if (sym)
467 indent -= 2;
468 }
470 static void check_conf(struct menu *menu)
471 {
472 struct symbol *sym;
473 struct menu *child;
475 if (!menu_is_visible(menu))
476 return;
478 sym = menu->sym;
479 if (sym && !sym_has_value(sym)) {
480 if (sym_is_changable(sym) ||
481 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
482 if (!conf_cnt++)
483 printf(_("*\n* Restart config...\n*\n"));
484 rootEntry = menu_get_parent_menu(menu);
485 conf(rootEntry);
486 }
487 }
489 for (child = menu->list; child; child = child->next)
490 check_conf(child);
491 }
493 int main(int ac, char **av)
494 {
495 int i = 1;
496 const char *name;
497 struct stat tmpstat;
499 if (ac > i && av[i][0] == '-') {
500 switch (av[i++][1]) {
501 case 'o':
502 input_mode = ask_new;
503 break;
504 case 's':
505 input_mode = ask_silent;
506 valid_stdin = isatty(0) && isatty(1) && isatty(2);
507 break;
508 case 'd':
509 input_mode = set_default;
510 break;
511 case 'D':
512 input_mode = set_default;
513 defconfig_file = av[i++];
514 if (!defconfig_file) {
515 printf(_("%s: No default config file specified\n"),
516 av[0]);
517 exit(1);
518 }
519 break;
520 case 'n':
521 input_mode = set_no;
522 break;
523 case 'm':
524 input_mode = set_mod;
525 break;
526 case 'y':
527 input_mode = set_yes;
528 break;
529 case 'r':
530 input_mode = set_random;
531 srandom(time(NULL));
532 break;
533 case 'h':
534 case '?':
535 fprintf(stderr, "See README for usage info\n");
536 exit(0);
537 }
538 }
539 name = av[i];
540 if (!name) {
541 printf(_("%s: Kconfig file missing\n"), av[0]);
542 exit(1);
543 }
544 conf_parse(name);
545 //zconfdump(stdout);
546 switch (input_mode) {
547 case set_default:
548 if (!defconfig_file)
549 defconfig_file = conf_get_default_confname();
550 if (conf_read(defconfig_file)) {
551 printf("***\n"
552 "*** Can't find default configuration \"%s\"!\n"
553 "***\n", defconfig_file);
554 exit(1);
555 }
556 break;
557 case ask_silent:
558 if (stat(".config", &tmpstat)) {
559 printf(_("***\n"
560 "*** You have not yet configured your kernel!\n"
561 "***\n"
562 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
563 "*** \"make menuconfig\" or \"make xconfig\").\n"
564 "***\n"));
565 exit(1);
566 }
567 case ask_all:
568 case ask_new:
569 conf_read(NULL);
570 break;
571 case set_no:
572 case set_mod:
573 case set_yes:
574 case set_random:
575 name = getenv("KCONFIG_ALLCONFIG");
576 if (name && !stat(name, &tmpstat)) {
577 conf_read_simple(name, S_DEF_USER);
578 break;
579 }
580 switch (input_mode) {
581 case set_no: name = "allno.config"; break;
582 case set_mod: name = "allmod.config"; break;
583 case set_yes: name = "allyes.config"; break;
584 case set_random: name = "allrandom.config"; break;
585 default: break;
586 }
587 if (!stat(name, &tmpstat))
588 conf_read_simple(name, S_DEF_USER);
589 else if (!stat("all.config", &tmpstat))
590 conf_read_simple("all.config", S_DEF_USER);
591 break;
592 default:
593 break;
594 }
596 if (input_mode != ask_silent) {
597 rootEntry = &rootmenu;
598 conf(&rootmenu);
599 if (input_mode == ask_all) {
600 input_mode = ask_silent;
601 valid_stdin = 1;
602 }
603 } else if (sym_change_count) {
604 name = getenv("KCONFIG_NOSILENTUPDATE");
605 if (name && *name) {
606 fprintf(stderr, _("\n*** Kernel configuration requires explicit update.\n\n"));
607 return 1;
608 }
609 } else
610 goto skip_check;
612 do {
613 conf_cnt = 0;
614 check_conf(&rootmenu);
615 } while (conf_cnt);
616 if (conf_write(NULL)) {
617 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
618 return 1;
619 }
620 skip_check:
621 if (input_mode == ask_silent && conf_write_autoconf()) {
622 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
623 return 1;
624 }
626 return 0;
627 }