ia64/linux-2.6.18-xen.hg

view scripts/kconfig/zconf.y @ 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 /*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 * Released under the terms of the GNU GPL v2.0.
5 */
7 #include <ctype.h>
8 #include <stdarg.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdbool.h>
14 #define LKC_DIRECT_LINK
15 #include "lkc.h"
17 #include "zconf.hash.c"
19 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
21 #define PRINTD 0x0001
22 #define DEBUG_PARSE 0x0002
24 int cdebug = PRINTD;
26 extern int zconflex(void);
27 static void zconfprint(const char *err, ...);
28 static void zconf_error(const char *err, ...);
29 static void zconferror(const char *err);
30 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
32 struct symbol *symbol_hash[257];
34 static struct menu *current_menu, *current_entry;
36 #define YYDEBUG 0
37 #if YYDEBUG
38 #define YYERROR_VERBOSE
39 #endif
40 %}
41 %expect 26
43 %union
44 {
45 char *string;
46 struct file *file;
47 struct symbol *symbol;
48 struct expr *expr;
49 struct menu *menu;
50 struct kconf_id *id;
51 }
53 %token <id>T_MAINMENU
54 %token <id>T_MENU
55 %token <id>T_ENDMENU
56 %token <id>T_SOURCE
57 %token <id>T_CHOICE
58 %token <id>T_ENDCHOICE
59 %token <id>T_COMMENT
60 %token <id>T_CONFIG
61 %token <id>T_MENUCONFIG
62 %token <id>T_HELP
63 %token <string> T_HELPTEXT
64 %token <id>T_IF
65 %token <id>T_ENDIF
66 %token <id>T_DEPENDS
67 %token <id>T_REQUIRES
68 %token <id>T_OPTIONAL
69 %token <id>T_PROMPT
70 %token <id>T_TYPE
71 %token <id>T_DEFAULT
72 %token <id>T_SELECT
73 %token <id>T_RANGE
74 %token <id>T_OPTION
75 %token <id>T_ON
76 %token <string> T_WORD
77 %token <string> T_WORD_QUOTE
78 %token T_UNEQUAL
79 %token T_CLOSE_PAREN
80 %token T_OPEN_PAREN
81 %token T_EOL
83 %left T_OR
84 %left T_AND
85 %left T_EQUAL T_UNEQUAL
86 %nonassoc T_NOT
88 %type <string> prompt
89 %type <symbol> symbol
90 %type <expr> expr
91 %type <expr> if_expr
92 %type <id> end
93 %type <id> option_name
94 %type <menu> if_entry menu_entry choice_entry
95 %type <string> symbol_option_arg
97 %destructor {
98 fprintf(stderr, "%s:%d: missing end statement for this entry\n",
99 $$->file->name, $$->lineno);
100 if (current_menu == $$)
101 menu_end_menu();
102 } if_entry menu_entry choice_entry
104 %%
105 input: stmt_list;
107 stmt_list:
108 /* empty */
109 | stmt_list common_stmt
110 | stmt_list choice_stmt
111 | stmt_list menu_stmt
112 | stmt_list T_MAINMENU prompt nl
113 | stmt_list end { zconf_error("unexpected end statement"); }
114 | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); }
115 | stmt_list option_name error T_EOL
116 {
117 zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
118 }
119 | stmt_list error T_EOL { zconf_error("invalid statement"); }
120 ;
122 option_name:
123 T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
124 ;
126 common_stmt:
127 T_EOL
128 | if_stmt
129 | comment_stmt
130 | config_stmt
131 | menuconfig_stmt
132 | source_stmt
133 ;
135 option_error:
136 T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); }
137 | error T_EOL { zconf_error("invalid option"); }
138 ;
141 /* config/menuconfig entry */
143 config_entry_start: T_CONFIG T_WORD T_EOL
144 {
145 struct symbol *sym = sym_lookup($2, 0);
146 sym->flags |= SYMBOL_OPTIONAL;
147 menu_add_entry(sym);
148 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
149 };
151 config_stmt: config_entry_start config_option_list
152 {
153 menu_end_entry();
154 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
155 };
157 menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
158 {
159 struct symbol *sym = sym_lookup($2, 0);
160 sym->flags |= SYMBOL_OPTIONAL;
161 menu_add_entry(sym);
162 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
163 };
165 menuconfig_stmt: menuconfig_entry_start config_option_list
166 {
167 if (current_entry->prompt)
168 current_entry->prompt->type = P_MENU;
169 else
170 zconfprint("warning: menuconfig statement without prompt");
171 menu_end_entry();
172 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
173 };
175 config_option_list:
176 /* empty */
177 | config_option_list config_option
178 | config_option_list symbol_option
179 | config_option_list depends
180 | config_option_list help
181 | config_option_list option_error
182 | config_option_list T_EOL
183 ;
185 config_option: T_TYPE prompt_stmt_opt T_EOL
186 {
187 menu_set_type($1->stype);
188 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
189 zconf_curname(), zconf_lineno(),
190 $1->stype);
191 };
193 config_option: T_PROMPT prompt if_expr T_EOL
194 {
195 menu_add_prompt(P_PROMPT, $2, $3);
196 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
197 };
199 config_option: T_DEFAULT expr if_expr T_EOL
200 {
201 menu_add_expr(P_DEFAULT, $2, $3);
202 if ($1->stype != S_UNKNOWN)
203 menu_set_type($1->stype);
204 printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
205 zconf_curname(), zconf_lineno(),
206 $1->stype);
207 };
209 config_option: T_SELECT T_WORD if_expr T_EOL
210 {
211 menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
212 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
213 };
215 config_option: T_RANGE symbol symbol if_expr T_EOL
216 {
217 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
218 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
219 };
221 symbol_option: T_OPTION symbol_option_list T_EOL
222 ;
224 symbol_option_list:
225 /* empty */
226 | symbol_option_list T_WORD symbol_option_arg
227 {
228 struct kconf_id *id = kconf_id_lookup($2, strlen($2));
229 if (id && id->flags & TF_OPTION)
230 menu_add_option(id->token, $3);
231 else
232 zconfprint("warning: ignoring unknown option %s", $2);
233 free($2);
234 };
236 symbol_option_arg:
237 /* empty */ { $$ = NULL; }
238 | T_EQUAL prompt { $$ = $2; }
239 ;
241 /* choice entry */
243 choice: T_CHOICE T_EOL
244 {
245 struct symbol *sym = sym_lookup(NULL, 0);
246 sym->flags |= SYMBOL_CHOICE;
247 menu_add_entry(sym);
248 menu_add_expr(P_CHOICE, NULL, NULL);
249 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
250 };
252 choice_entry: choice choice_option_list
253 {
254 $$ = menu_add_menu();
255 };
257 choice_end: end
258 {
259 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
260 menu_end_menu();
261 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
262 }
263 };
265 choice_stmt: choice_entry choice_block choice_end
266 ;
268 choice_option_list:
269 /* empty */
270 | choice_option_list choice_option
271 | choice_option_list depends
272 | choice_option_list help
273 | choice_option_list T_EOL
274 | choice_option_list option_error
275 ;
277 choice_option: T_PROMPT prompt if_expr T_EOL
278 {
279 menu_add_prompt(P_PROMPT, $2, $3);
280 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
281 };
283 choice_option: T_TYPE prompt_stmt_opt T_EOL
284 {
285 if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) {
286 menu_set_type($1->stype);
287 printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
288 zconf_curname(), zconf_lineno(),
289 $1->stype);
290 } else
291 YYERROR;
292 };
294 choice_option: T_OPTIONAL T_EOL
295 {
296 current_entry->sym->flags |= SYMBOL_OPTIONAL;
297 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
298 };
300 choice_option: T_DEFAULT T_WORD if_expr T_EOL
301 {
302 if ($1->stype == S_UNKNOWN) {
303 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
304 printd(DEBUG_PARSE, "%s:%d:default\n",
305 zconf_curname(), zconf_lineno());
306 } else
307 YYERROR;
308 };
310 choice_block:
311 /* empty */
312 | choice_block common_stmt
313 ;
315 /* if entry */
317 if_entry: T_IF expr nl
318 {
319 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
320 menu_add_entry(NULL);
321 menu_add_dep($2);
322 $$ = menu_add_menu();
323 };
325 if_end: end
326 {
327 if (zconf_endtoken($1, T_IF, T_ENDIF)) {
328 menu_end_menu();
329 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
330 }
331 };
333 if_stmt: if_entry if_block if_end
334 ;
336 if_block:
337 /* empty */
338 | if_block common_stmt
339 | if_block menu_stmt
340 | if_block choice_stmt
341 ;
343 /* menu entry */
345 menu: T_MENU prompt T_EOL
346 {
347 menu_add_entry(NULL);
348 menu_add_prompt(P_MENU, $2, NULL);
349 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
350 };
352 menu_entry: menu depends_list
353 {
354 $$ = menu_add_menu();
355 };
357 menu_end: end
358 {
359 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
360 menu_end_menu();
361 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
362 }
363 };
365 menu_stmt: menu_entry menu_block menu_end
366 ;
368 menu_block:
369 /* empty */
370 | menu_block common_stmt
371 | menu_block menu_stmt
372 | menu_block choice_stmt
373 ;
375 source_stmt: T_SOURCE prompt T_EOL
376 {
377 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
378 zconf_nextfile($2);
379 };
381 /* comment entry */
383 comment: T_COMMENT prompt T_EOL
384 {
385 menu_add_entry(NULL);
386 menu_add_prompt(P_COMMENT, $2, NULL);
387 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
388 };
390 comment_stmt: comment depends_list
391 {
392 menu_end_entry();
393 };
395 /* help option */
397 help_start: T_HELP T_EOL
398 {
399 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
400 zconf_starthelp();
401 };
403 help: help_start T_HELPTEXT
404 {
405 current_entry->sym->help = $2;
406 };
408 /* depends option */
410 depends_list:
411 /* empty */
412 | depends_list depends
413 | depends_list T_EOL
414 | depends_list option_error
415 ;
417 depends: T_DEPENDS T_ON expr T_EOL
418 {
419 menu_add_dep($3);
420 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
421 }
422 | T_DEPENDS expr T_EOL
423 {
424 menu_add_dep($2);
425 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
426 }
427 | T_REQUIRES expr T_EOL
428 {
429 menu_add_dep($2);
430 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
431 };
433 /* prompt statement */
435 prompt_stmt_opt:
436 /* empty */
437 | prompt if_expr
438 {
439 menu_add_prompt(P_PROMPT, $1, $2);
440 };
442 prompt: T_WORD
443 | T_WORD_QUOTE
444 ;
446 end: T_ENDMENU T_EOL { $$ = $1; }
447 | T_ENDCHOICE T_EOL { $$ = $1; }
448 | T_ENDIF T_EOL { $$ = $1; }
449 ;
451 nl:
452 T_EOL
453 | nl T_EOL
454 ;
456 if_expr: /* empty */ { $$ = NULL; }
457 | T_IF expr { $$ = $2; }
458 ;
460 expr: symbol { $$ = expr_alloc_symbol($1); }
461 | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
462 | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
463 | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
464 | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
465 | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
466 | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
467 ;
469 symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
470 | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
471 ;
473 %%
475 void conf_parse(const char *name)
476 {
477 struct symbol *sym;
478 int i;
480 zconf_initscan(name);
482 sym_init();
483 menu_init();
484 modules_sym = sym_lookup(NULL, 0);
485 modules_sym->type = S_BOOLEAN;
486 modules_sym->flags |= SYMBOL_AUTO;
487 rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
489 #if YYDEBUG
490 if (getenv("ZCONF_DEBUG"))
491 zconfdebug = 1;
492 #endif
493 zconfparse();
494 if (zconfnerrs)
495 exit(1);
496 if (!modules_sym->prop) {
497 struct property *prop;
499 prop = prop_alloc(P_DEFAULT, modules_sym);
500 prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
501 }
502 menu_finalize(&rootmenu);
503 for_all_symbols(i, sym) {
504 sym_check_deps(sym);
505 }
507 sym_change_count = 1;
508 }
510 const char *zconf_tokenname(int token)
511 {
512 switch (token) {
513 case T_MENU: return "menu";
514 case T_ENDMENU: return "endmenu";
515 case T_CHOICE: return "choice";
516 case T_ENDCHOICE: return "endchoice";
517 case T_IF: return "if";
518 case T_ENDIF: return "endif";
519 case T_DEPENDS: return "depends";
520 }
521 return "<token>";
522 }
524 static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
525 {
526 if (id->token != endtoken) {
527 zconf_error("unexpected '%s' within %s block",
528 kconf_id_strings + id->name, zconf_tokenname(starttoken));
529 zconfnerrs++;
530 return false;
531 }
532 if (current_menu->file != current_file) {
533 zconf_error("'%s' in different file than '%s'",
534 kconf_id_strings + id->name, zconf_tokenname(starttoken));
535 fprintf(stderr, "%s:%d: location of the '%s'\n",
536 current_menu->file->name, current_menu->lineno,
537 zconf_tokenname(starttoken));
538 zconfnerrs++;
539 return false;
540 }
541 return true;
542 }
544 static void zconfprint(const char *err, ...)
545 {
546 va_list ap;
548 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
549 va_start(ap, err);
550 vfprintf(stderr, err, ap);
551 va_end(ap);
552 fprintf(stderr, "\n");
553 }
555 static void zconf_error(const char *err, ...)
556 {
557 va_list ap;
559 zconfnerrs++;
560 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
561 va_start(ap, err);
562 vfprintf(stderr, err, ap);
563 va_end(ap);
564 fprintf(stderr, "\n");
565 }
567 static void zconferror(const char *err)
568 {
569 #if YYDEBUG
570 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
571 #endif
572 }
574 void print_quoted_string(FILE *out, const char *str)
575 {
576 const char *p;
577 int len;
579 putc('"', out);
580 while ((p = strchr(str, '"'))) {
581 len = p - str;
582 if (len)
583 fprintf(out, "%.*s", len, str);
584 fputs("\\\"", out);
585 str = p + 1;
586 }
587 fputs(str, out);
588 putc('"', out);
589 }
591 void print_symbol(FILE *out, struct menu *menu)
592 {
593 struct symbol *sym = menu->sym;
594 struct property *prop;
596 if (sym_is_choice(sym))
597 fprintf(out, "choice\n");
598 else
599 fprintf(out, "config %s\n", sym->name);
600 switch (sym->type) {
601 case S_BOOLEAN:
602 fputs(" boolean\n", out);
603 break;
604 case S_TRISTATE:
605 fputs(" tristate\n", out);
606 break;
607 case S_STRING:
608 fputs(" string\n", out);
609 break;
610 case S_INT:
611 fputs(" integer\n", out);
612 break;
613 case S_HEX:
614 fputs(" hex\n", out);
615 break;
616 default:
617 fputs(" ???\n", out);
618 break;
619 }
620 for (prop = sym->prop; prop; prop = prop->next) {
621 if (prop->menu != menu)
622 continue;
623 switch (prop->type) {
624 case P_PROMPT:
625 fputs(" prompt ", out);
626 print_quoted_string(out, prop->text);
627 if (!expr_is_yes(prop->visible.expr)) {
628 fputs(" if ", out);
629 expr_fprint(prop->visible.expr, out);
630 }
631 fputc('\n', out);
632 break;
633 case P_DEFAULT:
634 fputs( " default ", out);
635 expr_fprint(prop->expr, out);
636 if (!expr_is_yes(prop->visible.expr)) {
637 fputs(" if ", out);
638 expr_fprint(prop->visible.expr, out);
639 }
640 fputc('\n', out);
641 break;
642 case P_CHOICE:
643 fputs(" #choice value\n", out);
644 break;
645 default:
646 fprintf(out, " unknown prop %d!\n", prop->type);
647 break;
648 }
649 }
650 if (sym->help) {
651 int len = strlen(sym->help);
652 while (sym->help[--len] == '\n')
653 sym->help[len] = 0;
654 fprintf(out, " help\n%s\n", sym->help);
655 }
656 fputc('\n', out);
657 }
659 void zconfdump(FILE *out)
660 {
661 struct property *prop;
662 struct symbol *sym;
663 struct menu *menu;
665 menu = rootmenu.list;
666 while (menu) {
667 if ((sym = menu->sym))
668 print_symbol(out, menu);
669 else if ((prop = menu->prompt)) {
670 switch (prop->type) {
671 case P_COMMENT:
672 fputs("\ncomment ", out);
673 print_quoted_string(out, prop->text);
674 fputs("\n", out);
675 break;
676 case P_MENU:
677 fputs("\nmenu ", out);
678 print_quoted_string(out, prop->text);
679 fputs("\n", out);
680 break;
681 default:
682 ;
683 }
684 if (!expr_is_yes(prop->visible.expr)) {
685 fputs(" depends ", out);
686 expr_fprint(prop->visible.expr, out);
687 fputc('\n', out);
688 }
689 fputs("\n", out);
690 }
692 if (menu->list)
693 menu = menu->list;
694 else if (menu->next)
695 menu = menu->next;
696 else while ((menu = menu->parent)) {
697 if (menu->prompt && menu->prompt->type == P_MENU)
698 fputs("\nendmenu\n", out);
699 if (menu->next) {
700 menu = menu->next;
701 break;
702 }
703 }
704 }
705 }
707 #include "lex.zconf.c"
708 #include "util.c"
709 #include "confdata.c"
710 #include "expr.c"
711 #include "symbol.c"
712 #include "menu.c"