ia64/linux-2.6.18-xen.hg

view scripts/basic/fixdep.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 * "Optimize" a list of dependencies as spit out by gcc -MD
3 * for the kernel build
4 * ===========================================================================
5 *
6 * Author Kai Germaschewski
7 * Copyright 2002 by Kai Germaschewski <kai.germaschewski@gmx.de>
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 *
12 *
13 * Introduction:
14 *
15 * gcc produces a very nice and correct list of dependencies which
16 * tells make when to remake a file.
17 *
18 * To use this list as-is however has the drawback that virtually
19 * every file in the kernel includes <linux/config.h> which then again
20 * includes <linux/autoconf.h>
21 *
22 * If the user re-runs make *config, linux/autoconf.h will be
23 * regenerated. make notices that and will rebuild every file which
24 * includes autoconf.h, i.e. basically all files. This is extremely
25 * annoying if the user just changed CONFIG_HIS_DRIVER from n to m.
26 *
27 * So we play the same trick that "mkdep" played before. We replace
28 * the dependency on linux/autoconf.h by a dependency on every config
29 * option which is mentioned in any of the listed prequisites.
30 *
31 * To be exact, split-include populates a tree in include/config/,
32 * e.g. include/config/his/driver.h, which contains the #define/#undef
33 * for the CONFIG_HIS_DRIVER option.
34 *
35 * So if the user changes his CONFIG_HIS_DRIVER option, only the objects
36 * which depend on "include/linux/config/his/driver.h" will be rebuilt,
37 * so most likely only his driver ;-)
38 *
39 * The idea above dates, by the way, back to Michael E Chastain, AFAIK.
40 *
41 * So to get dependencies right, there are two issues:
42 * o if any of the files the compiler read changed, we need to rebuild
43 * o if the command line given to the compile the file changed, we
44 * better rebuild as well.
45 *
46 * The former is handled by using the -MD output, the later by saving
47 * the command line used to compile the old object and comparing it
48 * to the one we would now use.
49 *
50 * Again, also this idea is pretty old and has been discussed on
51 * kbuild-devel a long time ago. I don't have a sensibly working
52 * internet connection right now, so I rather don't mention names
53 * without double checking.
54 *
55 * This code here has been based partially based on mkdep.c, which
56 * says the following about its history:
57 *
58 * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
59 * This is a C version of syncdep.pl by Werner Almesberger.
60 *
61 *
62 * It is invoked as
63 *
64 * fixdep <depfile> <target> <cmdline>
65 *
66 * and will read the dependency file <depfile>
67 *
68 * The transformed dependency snipped is written to stdout.
69 *
70 * It first generates a line
71 *
72 * cmd_<target> = <cmdline>
73 *
74 * and then basically copies the .<target>.d file to stdout, in the
75 * process filtering out the dependency on linux/autoconf.h and adding
76 * dependencies on include/config/my/option.h for every
77 * CONFIG_MY_OPTION encountered in any of the prequisites.
78 *
79 * It will also filter out all the dependencies on *.ver. We need
80 * to make sure that the generated version checksum are globally up
81 * to date before even starting the recursive build, so it's too late
82 * at this point anyway.
83 *
84 * The algorithm to grep for "CONFIG_..." is bit unusual, but should
85 * be fast ;-) We don't even try to really parse the header files, but
86 * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will
87 * be picked up as well. It's not a problem with respect to
88 * correctness, since that can only give too many dependencies, thus
89 * we cannot miss a rebuild. Since people tend to not mention totally
90 * unrelated CONFIG_ options all over the place, it's not an
91 * efficiency problem either.
92 *
93 * (Note: it'd be easy to port over the complete mkdep state machine,
94 * but I don't think the added complexity is worth it)
95 */
96 /*
97 * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto
98 * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not
99 * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as
100 * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h,
101 * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that
102 * those files will have correct dependencies.
103 */
105 #include <sys/types.h>
106 #include <sys/stat.h>
107 #include <sys/mman.h>
108 #include <unistd.h>
109 #include <fcntl.h>
110 #include <string.h>
111 #include <stdlib.h>
112 #include <stdio.h>
113 #include <limits.h>
114 #include <ctype.h>
115 #include <arpa/inet.h>
117 #define INT_CONF ntohl(0x434f4e46)
118 #define INT_ONFI ntohl(0x4f4e4649)
119 #define INT_NFIG ntohl(0x4e464947)
120 #define INT_FIG_ ntohl(0x4649475f)
122 char *target;
123 char *depfile;
124 char *cmdline;
126 void usage(void)
128 {
129 fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
130 exit(1);
131 }
133 /*
134 * Print out the commandline prefixed with cmd_<target filename> :=
135 */
136 void print_cmdline(void)
137 {
138 printf("cmd_%s := %s\n\n", target, cmdline);
139 }
141 char * str_config = NULL;
142 int size_config = 0;
143 int len_config = 0;
145 /*
146 * Grow the configuration string to a desired length.
147 * Usually the first growth is plenty.
148 */
149 void grow_config(int len)
150 {
151 while (len_config + len > size_config) {
152 if (size_config == 0)
153 size_config = 2048;
154 str_config = realloc(str_config, size_config *= 2);
155 if (str_config == NULL)
156 { perror("fixdep:malloc"); exit(1); }
157 }
158 }
162 /*
163 * Lookup a value in the configuration string.
164 */
165 int is_defined_config(const char * name, int len)
166 {
167 const char * pconfig;
168 const char * plast = str_config + len_config - len;
169 for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
170 if (pconfig[ -1] == '\n'
171 && pconfig[len] == '\n'
172 && !memcmp(pconfig, name, len))
173 return 1;
174 }
175 return 0;
176 }
178 /*
179 * Add a new value to the configuration string.
180 */
181 void define_config(const char * name, int len)
182 {
183 grow_config(len + 1);
185 memcpy(str_config+len_config, name, len);
186 len_config += len;
187 str_config[len_config++] = '\n';
188 }
190 /*
191 * Clear the set of configuration strings.
192 */
193 void clear_config(void)
194 {
195 len_config = 0;
196 define_config("", 0);
197 }
199 /*
200 * Record the use of a CONFIG_* word.
201 */
202 void use_config(char *m, int slen)
203 {
204 char s[PATH_MAX];
205 char *p;
207 if (is_defined_config(m, slen))
208 return;
210 define_config(m, slen);
212 memcpy(s, m, slen); s[slen] = 0;
214 for (p = s; p < s + slen; p++) {
215 if (*p == '_')
216 *p = '/';
217 else
218 *p = tolower((int)*p);
219 }
220 printf(" $(wildcard include/config/%s.h) \\\n", s);
221 }
223 void parse_config_file(char *map, size_t len)
224 {
225 int *end = (int *) (map + len);
226 /* start at +1, so that p can never be < map */
227 int *m = (int *) map + 1;
228 char *p, *q;
230 for (; m < end; m++) {
231 if (*m == INT_CONF) { p = (char *) m ; goto conf; }
232 if (*m == INT_ONFI) { p = (char *) m-1; goto conf; }
233 if (*m == INT_NFIG) { p = (char *) m-2; goto conf; }
234 if (*m == INT_FIG_) { p = (char *) m-3; goto conf; }
235 continue;
236 conf:
237 if (p > map + len - 7)
238 continue;
239 if (memcmp(p, "CONFIG_", 7))
240 continue;
241 for (q = p + 7; q < map + len; q++) {
242 if (!(isalnum(*q) || *q == '_'))
243 goto found;
244 }
245 continue;
247 found:
248 use_config(p+7, q-p-7);
249 }
250 }
252 /* test is s ends in sub */
253 int strrcmp(char *s, char *sub)
254 {
255 int slen = strlen(s);
256 int sublen = strlen(sub);
258 if (sublen > slen)
259 return 1;
261 return memcmp(s + slen - sublen, sub, sublen);
262 }
264 void do_config_file(char *filename)
265 {
266 struct stat st;
267 int fd;
268 void *map;
270 fd = open(filename, O_RDONLY);
271 if (fd < 0) {
272 fprintf(stderr, "fixdep: ");
273 perror(filename);
274 exit(2);
275 }
276 fstat(fd, &st);
277 if (st.st_size == 0) {
278 close(fd);
279 return;
280 }
281 map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
282 if ((long) map == -1) {
283 perror("fixdep: mmap");
284 close(fd);
285 return;
286 }
288 parse_config_file(map, st.st_size);
290 munmap(map, st.st_size);
292 close(fd);
293 }
295 void parse_dep_file(void *map, size_t len)
296 {
297 char *m = map;
298 char *end = m + len;
299 char *p;
300 char s[PATH_MAX];
302 p = strchr(m, ':');
303 if (!p) {
304 fprintf(stderr, "fixdep: parse error\n");
305 exit(1);
306 }
307 memcpy(s, m, p-m); s[p-m] = 0;
308 printf("deps_%s := \\\n", target);
309 m = p+1;
311 clear_config();
313 while (m < end) {
314 while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
315 m++;
316 p = m;
317 while (p < end && *p != ' ') p++;
318 if (p == end) {
319 do p--; while (!isalnum(*p));
320 p++;
321 }
322 memcpy(s, m, p-m); s[p-m] = 0;
323 if (strrcmp(s, "include/linux/autoconf.h") &&
324 strrcmp(s, "arch/um/include/uml-config.h") &&
325 strrcmp(s, ".ver")) {
326 printf(" %s \\\n", s);
327 do_config_file(s);
328 }
329 m = p + 1;
330 }
331 printf("\n%s: $(deps_%s)\n\n", target, target);
332 printf("$(deps_%s):\n", target);
333 }
335 void print_deps(void)
336 {
337 struct stat st;
338 int fd;
339 void *map;
341 fd = open(depfile, O_RDONLY);
342 if (fd < 0) {
343 fprintf(stderr, "fixdep: ");
344 perror(depfile);
345 exit(2);
346 }
347 fstat(fd, &st);
348 if (st.st_size == 0) {
349 fprintf(stderr,"fixdep: %s is empty\n",depfile);
350 close(fd);
351 return;
352 }
353 map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
354 if ((long) map == -1) {
355 perror("fixdep: mmap");
356 close(fd);
357 return;
358 }
360 parse_dep_file(map, st.st_size);
362 munmap(map, st.st_size);
364 close(fd);
365 }
367 void traps(void)
368 {
369 static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
371 if (*(int *)test != INT_CONF) {
372 fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n",
373 *(int *)test);
374 exit(2);
375 }
376 }
378 int main(int argc, char *argv[])
379 {
380 traps();
382 if (argc != 4)
383 usage();
385 depfile = argv[1];
386 target = argv[2];
387 cmdline = argv[3];
389 print_cmdline();
390 print_deps();
392 return 0;
393 }