ia64/linux-2.6.18-xen.hg

view scripts/kconfig/kxgettext.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 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
3 *
4 * Released under the terms of the GNU GPL v2.0
5 */
7 #include <stdlib.h>
8 #include <string.h>
10 #define LKC_DIRECT_LINK
11 #include "lkc.h"
13 static char *escape(const char* text, char *bf, int len)
14 {
15 char *bfp = bf;
16 int multiline = strchr(text, '\n') != NULL;
17 int eol = 0;
18 int textlen = strlen(text);
20 if ((textlen > 0) && (text[textlen-1] == '\n'))
21 eol = 1;
23 *bfp++ = '"';
24 --len;
26 if (multiline) {
27 *bfp++ = '"';
28 *bfp++ = '\n';
29 *bfp++ = '"';
30 len -= 3;
31 }
33 while (*text != '\0' && len > 1) {
34 if (*text == '"')
35 *bfp++ = '\\';
36 else if (*text == '\n') {
37 *bfp++ = '\\';
38 *bfp++ = 'n';
39 *bfp++ = '"';
40 *bfp++ = '\n';
41 *bfp++ = '"';
42 len -= 5;
43 ++text;
44 goto next;
45 }
46 *bfp++ = *text++;
47 next:
48 --len;
49 }
51 if (multiline && eol)
52 bfp -= 3;
54 *bfp++ = '"';
55 *bfp = '\0';
57 return bf;
58 }
60 struct file_line {
61 struct file_line *next;
62 char* file;
63 int lineno;
64 };
66 static struct file_line *file_line__new(char *file, int lineno)
67 {
68 struct file_line *self = malloc(sizeof(*self));
70 if (self == NULL)
71 goto out;
73 self->file = file;
74 self->lineno = lineno;
75 self->next = NULL;
76 out:
77 return self;
78 }
80 struct message {
81 const char *msg;
82 const char *option;
83 struct message *next;
84 struct file_line *files;
85 };
87 static struct message *message__list;
89 static struct message *message__new(const char *msg, char *option, char *file, int lineno)
90 {
91 struct message *self = malloc(sizeof(*self));
93 if (self == NULL)
94 goto out;
96 self->files = file_line__new(file, lineno);
97 if (self->files == NULL)
98 goto out_fail;
100 self->msg = strdup(msg);
101 if (self->msg == NULL)
102 goto out_fail_msg;
104 self->option = option;
105 self->next = NULL;
106 out:
107 return self;
108 out_fail_msg:
109 free(self->files);
110 out_fail:
111 free(self);
112 self = NULL;
113 goto out;
114 }
116 static struct message *mesage__find(const char *msg)
117 {
118 struct message *m = message__list;
120 while (m != NULL) {
121 if (strcmp(m->msg, msg) == 0)
122 break;
123 m = m->next;
124 }
126 return m;
127 }
129 static int message__add_file_line(struct message *self, char *file, int lineno)
130 {
131 int rc = -1;
132 struct file_line *fl = file_line__new(file, lineno);
134 if (fl == NULL)
135 goto out;
137 fl->next = self->files;
138 self->files = fl;
139 rc = 0;
140 out:
141 return rc;
142 }
144 static int message__add(const char *msg, char *option, char *file, int lineno)
145 {
146 int rc = 0;
147 char bf[16384];
148 char *escaped = escape(msg, bf, sizeof(bf));
149 struct message *m = mesage__find(escaped);
151 if (m != NULL)
152 rc = message__add_file_line(m, file, lineno);
153 else {
154 m = message__new(escaped, option, file, lineno);
156 if (m != NULL) {
157 m->next = message__list;
158 message__list = m;
159 } else
160 rc = -1;
161 }
162 return rc;
163 }
165 void menu_build_message_list(struct menu *menu)
166 {
167 struct menu *child;
169 message__add(menu_get_prompt(menu), NULL,
170 menu->file == NULL ? "Root Menu" : menu->file->name,
171 menu->lineno);
173 if (menu->sym != NULL && menu->sym->help != NULL)
174 message__add(menu->sym->help, menu->sym->name,
175 menu->file == NULL ? "Root Menu" : menu->file->name,
176 menu->lineno);
178 for (child = menu->list; child != NULL; child = child->next)
179 if (child->prompt != NULL)
180 menu_build_message_list(child);
181 }
183 static void message__print_file_lineno(struct message *self)
184 {
185 struct file_line *fl = self->files;
187 putchar('\n');
188 if (self->option != NULL)
189 printf("# %s:00000\n", self->option);
191 printf("#: %s:%d", fl->file, fl->lineno);
192 fl = fl->next;
194 while (fl != NULL) {
195 printf(", %s:%d", fl->file, fl->lineno);
196 fl = fl->next;
197 }
199 putchar('\n');
200 }
202 static void message__print_gettext_msgid_msgstr(struct message *self)
203 {
204 message__print_file_lineno(self);
206 printf("msgid %s\n"
207 "msgstr \"\"\n", self->msg);
208 }
210 void menu__xgettext(void)
211 {
212 struct message *m = message__list;
214 while (m != NULL) {
215 message__print_gettext_msgid_msgstr(m);
216 m = m->next;
217 }
218 }
220 int main(int ac, char **av)
221 {
222 conf_parse(av[1]);
224 menu_build_message_list(menu_get_root_menu(NULL));
225 menu__xgettext();
226 return 0;
227 }