ia64/linux-2.6.18-xen.hg

annotate scripts/basic/docproc.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
rev   line source
ian@0 1 /*
ian@0 2 * docproc is a simple preprocessor for the template files
ian@0 3 * used as placeholders for the kernel internal documentation.
ian@0 4 * docproc is used for documentation-frontend and
ian@0 5 * dependency-generator.
ian@0 6 * The two usages have in common that they require
ian@0 7 * some knowledge of the .tmpl syntax, therefore they
ian@0 8 * are kept together.
ian@0 9 *
ian@0 10 * documentation-frontend
ian@0 11 * Scans the template file and call kernel-doc for
ian@0 12 * all occurrences of ![EIF]file
ian@0 13 * Beforehand each referenced file are scanned for
ian@0 14 * any exported sympols "EXPORT_SYMBOL()" statements.
ian@0 15 * This is used to create proper -function and
ian@0 16 * -nofunction arguments in calls to kernel-doc.
ian@0 17 * Usage: docproc doc file.tmpl
ian@0 18 *
ian@0 19 * dependency-generator:
ian@0 20 * Scans the template file and list all files
ian@0 21 * referenced in a format recognized by make.
ian@0 22 * Usage: docproc depend file.tmpl
ian@0 23 * Writes dependency information to stdout
ian@0 24 * in the following format:
ian@0 25 * file.tmpl src.c src2.c
ian@0 26 * The filenames are obtained from the following constructs:
ian@0 27 * !Efilename
ian@0 28 * !Ifilename
ian@0 29 * !Dfilename
ian@0 30 * !Ffilename
ian@0 31 *
ian@0 32 */
ian@0 33
ian@0 34 #include <stdio.h>
ian@0 35 #include <stdlib.h>
ian@0 36 #include <string.h>
ian@0 37 #include <ctype.h>
ian@0 38 #include <unistd.h>
ian@0 39 #include <limits.h>
ian@0 40 #include <sys/types.h>
ian@0 41 #include <sys/wait.h>
ian@0 42
ian@0 43 /* exitstatus is used to keep track of any failing calls to kernel-doc,
ian@0 44 * but execution continues. */
ian@0 45 int exitstatus = 0;
ian@0 46
ian@0 47 typedef void DFL(char *);
ian@0 48 DFL *defaultline;
ian@0 49
ian@0 50 typedef void FILEONLY(char * file);
ian@0 51 FILEONLY *internalfunctions;
ian@0 52 FILEONLY *externalfunctions;
ian@0 53 FILEONLY *symbolsonly;
ian@0 54
ian@0 55 typedef void FILELINE(char * file, char * line);
ian@0 56 FILELINE * singlefunctions;
ian@0 57 FILELINE * entity_system;
ian@0 58
ian@0 59 #define MAXLINESZ 2048
ian@0 60 #define MAXFILES 250
ian@0 61 #define KERNELDOCPATH "scripts/"
ian@0 62 #define KERNELDOC "kernel-doc"
ian@0 63 #define DOCBOOK "-docbook"
ian@0 64 #define FUNCTION "-function"
ian@0 65 #define NOFUNCTION "-nofunction"
ian@0 66
ian@0 67 void usage (void)
ian@0 68 {
ian@0 69 fprintf(stderr, "Usage: docproc {doc|depend} file\n");
ian@0 70 fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
ian@0 71 fprintf(stderr, "doc: frontend when generating kernel documentation\n");
ian@0 72 fprintf(stderr, "depend: generate list of files referenced within file\n");
ian@0 73 }
ian@0 74
ian@0 75 /*
ian@0 76 * Execute kernel-doc with parameters givin in svec
ian@0 77 */
ian@0 78 void exec_kernel_doc(char **svec)
ian@0 79 {
ian@0 80 pid_t pid;
ian@0 81 int ret;
ian@0 82 char real_filename[PATH_MAX + 1];
ian@0 83 /* Make sure output generated so far are flushed */
ian@0 84 fflush(stdout);
ian@0 85 switch(pid=fork()) {
ian@0 86 case -1:
ian@0 87 perror("fork");
ian@0 88 exit(1);
ian@0 89 case 0:
ian@0 90 memset(real_filename, 0, sizeof(real_filename));
ian@0 91 strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
ian@0 92 strncat(real_filename, KERNELDOCPATH KERNELDOC,
ian@0 93 PATH_MAX - strlen(real_filename));
ian@0 94 execvp(real_filename, svec);
ian@0 95 fprintf(stderr, "exec ");
ian@0 96 perror(real_filename);
ian@0 97 exit(1);
ian@0 98 default:
ian@0 99 waitpid(pid, &ret ,0);
ian@0 100 }
ian@0 101 if (WIFEXITED(ret))
ian@0 102 exitstatus |= WEXITSTATUS(ret);
ian@0 103 else
ian@0 104 exitstatus = 0xff;
ian@0 105 }
ian@0 106
ian@0 107 /* Types used to create list of all exported symbols in a number of files */
ian@0 108 struct symbols
ian@0 109 {
ian@0 110 char *name;
ian@0 111 };
ian@0 112
ian@0 113 struct symfile
ian@0 114 {
ian@0 115 char *filename;
ian@0 116 struct symbols *symbollist;
ian@0 117 int symbolcnt;
ian@0 118 };
ian@0 119
ian@0 120 struct symfile symfilelist[MAXFILES];
ian@0 121 int symfilecnt = 0;
ian@0 122
ian@0 123 void add_new_symbol(struct symfile *sym, char * symname)
ian@0 124 {
ian@0 125 sym->symbollist =
ian@0 126 realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
ian@0 127 sym->symbollist[sym->symbolcnt++].name = strdup(symname);
ian@0 128 }
ian@0 129
ian@0 130 /* Add a filename to the list */
ian@0 131 struct symfile * add_new_file(char * filename)
ian@0 132 {
ian@0 133 symfilelist[symfilecnt++].filename = strdup(filename);
ian@0 134 return &symfilelist[symfilecnt - 1];
ian@0 135 }
ian@0 136 /* Check if file already are present in the list */
ian@0 137 struct symfile * filename_exist(char * filename)
ian@0 138 {
ian@0 139 int i;
ian@0 140 for (i=0; i < symfilecnt; i++)
ian@0 141 if (strcmp(symfilelist[i].filename, filename) == 0)
ian@0 142 return &symfilelist[i];
ian@0 143 return NULL;
ian@0 144 }
ian@0 145
ian@0 146 /*
ian@0 147 * List all files referenced within the template file.
ian@0 148 * Files are separated by tabs.
ian@0 149 */
ian@0 150 void adddep(char * file) { printf("\t%s", file); }
ian@0 151 void adddep2(char * file, char * line) { line = line; adddep(file); }
ian@0 152 void noaction(char * line) { line = line; }
ian@0 153 void noaction2(char * file, char * line) { file = file; line = line; }
ian@0 154
ian@0 155 /* Echo the line without further action */
ian@0 156 void printline(char * line) { printf("%s", line); }
ian@0 157
ian@0 158 /*
ian@0 159 * Find all symbols exported with EXPORT_SYMBOL and EXPORT_SYMBOL_GPL
ian@0 160 * in filename.
ian@0 161 * All symbols located are stored in symfilelist.
ian@0 162 */
ian@0 163 void find_export_symbols(char * filename)
ian@0 164 {
ian@0 165 FILE * fp;
ian@0 166 struct symfile *sym;
ian@0 167 char line[MAXLINESZ];
ian@0 168 if (filename_exist(filename) == NULL) {
ian@0 169 char real_filename[PATH_MAX + 1];
ian@0 170 memset(real_filename, 0, sizeof(real_filename));
ian@0 171 strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
ian@0 172 strncat(real_filename, filename,
ian@0 173 PATH_MAX - strlen(real_filename));
ian@0 174 sym = add_new_file(filename);
ian@0 175 fp = fopen(real_filename, "r");
ian@0 176 if (fp == NULL)
ian@0 177 {
ian@0 178 fprintf(stderr, "docproc: ");
ian@0 179 perror(real_filename);
ian@0 180 }
ian@0 181 while(fgets(line, MAXLINESZ, fp)) {
ian@0 182 char *p;
ian@0 183 char *e;
ian@0 184 if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) ||
ian@0 185 ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) {
ian@0 186 /* Skip EXPORT_SYMBOL{_GPL} */
ian@0 187 while (isalnum(*p) || *p == '_')
ian@0 188 p++;
ian@0 189 /* Remove paranteses and additional ws */
ian@0 190 while (isspace(*p))
ian@0 191 p++;
ian@0 192 if (*p != '(')
ian@0 193 continue; /* Syntax error? */
ian@0 194 else
ian@0 195 p++;
ian@0 196 while (isspace(*p))
ian@0 197 p++;
ian@0 198 e = p;
ian@0 199 while (isalnum(*e) || *e == '_')
ian@0 200 e++;
ian@0 201 *e = '\0';
ian@0 202 add_new_symbol(sym, p);
ian@0 203 }
ian@0 204 }
ian@0 205 fclose(fp);
ian@0 206 }
ian@0 207 }
ian@0 208
ian@0 209 /*
ian@0 210 * Document all external or internal functions in a file.
ian@0 211 * Call kernel-doc with following parameters:
ian@0 212 * kernel-doc -docbook -nofunction function_name1 filename
ian@0 213 * function names are obtained from all the the src files
ian@0 214 * by find_export_symbols.
ian@0 215 * intfunc uses -nofunction
ian@0 216 * extfunc uses -function
ian@0 217 */
ian@0 218 void docfunctions(char * filename, char * type)
ian@0 219 {
ian@0 220 int i,j;
ian@0 221 int symcnt = 0;
ian@0 222 int idx = 0;
ian@0 223 char **vec;
ian@0 224
ian@0 225 for (i=0; i <= symfilecnt; i++)
ian@0 226 symcnt += symfilelist[i].symbolcnt;
ian@0 227 vec = malloc((2 + 2 * symcnt + 2) * sizeof(char*));
ian@0 228 if (vec == NULL) {
ian@0 229 perror("docproc: ");
ian@0 230 exit(1);
ian@0 231 }
ian@0 232 vec[idx++] = KERNELDOC;
ian@0 233 vec[idx++] = DOCBOOK;
ian@0 234 for (i=0; i < symfilecnt; i++) {
ian@0 235 struct symfile * sym = &symfilelist[i];
ian@0 236 for (j=0; j < sym->symbolcnt; j++) {
ian@0 237 vec[idx++] = type;
ian@0 238 vec[idx++] = sym->symbollist[j].name;
ian@0 239 }
ian@0 240 }
ian@0 241 vec[idx++] = filename;
ian@0 242 vec[idx] = NULL;
ian@0 243 printf("<!-- %s -->\n", filename);
ian@0 244 exec_kernel_doc(vec);
ian@0 245 fflush(stdout);
ian@0 246 free(vec);
ian@0 247 }
ian@0 248 void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); }
ian@0 249 void extfunc(char * filename) { docfunctions(filename, FUNCTION); }
ian@0 250
ian@0 251 /*
ian@0 252 * Document spåecific function(s) in a file.
ian@0 253 * Call kernel-doc with the following parameters:
ian@0 254 * kernel-doc -docbook -function function1 [-function function2]
ian@0 255 */
ian@0 256 void singfunc(char * filename, char * line)
ian@0 257 {
ian@0 258 char *vec[200]; /* Enough for specific functions */
ian@0 259 int i, idx = 0;
ian@0 260 int startofsym = 1;
ian@0 261 vec[idx++] = KERNELDOC;
ian@0 262 vec[idx++] = DOCBOOK;
ian@0 263
ian@0 264 /* Split line up in individual parameters preceeded by FUNCTION */
ian@0 265 for (i=0; line[i]; i++) {
ian@0 266 if (isspace(line[i])) {
ian@0 267 line[i] = '\0';
ian@0 268 startofsym = 1;
ian@0 269 continue;
ian@0 270 }
ian@0 271 if (startofsym) {
ian@0 272 startofsym = 0;
ian@0 273 vec[idx++] = FUNCTION;
ian@0 274 vec[idx++] = &line[i];
ian@0 275 }
ian@0 276 }
ian@0 277 vec[idx++] = filename;
ian@0 278 vec[idx] = NULL;
ian@0 279 exec_kernel_doc(vec);
ian@0 280 }
ian@0 281
ian@0 282 /*
ian@0 283 * Parse file, calling action specific functions for:
ian@0 284 * 1) Lines containing !E
ian@0 285 * 2) Lines containing !I
ian@0 286 * 3) Lines containing !D
ian@0 287 * 4) Lines containing !F
ian@0 288 * 5) Default lines - lines not matching the above
ian@0 289 */
ian@0 290 void parse_file(FILE *infile)
ian@0 291 {
ian@0 292 char line[MAXLINESZ];
ian@0 293 char * s;
ian@0 294 while(fgets(line, MAXLINESZ, infile)) {
ian@0 295 if (line[0] == '!') {
ian@0 296 s = line + 2;
ian@0 297 switch (line[1]) {
ian@0 298 case 'E':
ian@0 299 while (*s && !isspace(*s)) s++;
ian@0 300 *s = '\0';
ian@0 301 externalfunctions(line+2);
ian@0 302 break;
ian@0 303 case 'I':
ian@0 304 while (*s && !isspace(*s)) s++;
ian@0 305 *s = '\0';
ian@0 306 internalfunctions(line+2);
ian@0 307 break;
ian@0 308 case 'D':
ian@0 309 while (*s && !isspace(*s)) s++;
ian@0 310 *s = '\0';
ian@0 311 symbolsonly(line+2);
ian@0 312 break;
ian@0 313 case 'F':
ian@0 314 /* filename */
ian@0 315 while (*s && !isspace(*s)) s++;
ian@0 316 *s++ = '\0';
ian@0 317 /* function names */
ian@0 318 while (isspace(*s))
ian@0 319 s++;
ian@0 320 singlefunctions(line +2, s);
ian@0 321 break;
ian@0 322 default:
ian@0 323 defaultline(line);
ian@0 324 }
ian@0 325 }
ian@0 326 else {
ian@0 327 defaultline(line);
ian@0 328 }
ian@0 329 }
ian@0 330 fflush(stdout);
ian@0 331 }
ian@0 332
ian@0 333
ian@0 334 int main(int argc, char *argv[])
ian@0 335 {
ian@0 336 FILE * infile;
ian@0 337 if (argc != 3) {
ian@0 338 usage();
ian@0 339 exit(1);
ian@0 340 }
ian@0 341 /* Open file, exit on error */
ian@0 342 infile = fopen(argv[2], "r");
ian@0 343 if (infile == NULL) {
ian@0 344 fprintf(stderr, "docproc: ");
ian@0 345 perror(argv[2]);
ian@0 346 exit(2);
ian@0 347 }
ian@0 348
ian@0 349 if (strcmp("doc", argv[1]) == 0)
ian@0 350 {
ian@0 351 /* Need to do this in two passes.
ian@0 352 * First pass is used to collect all symbols exported
ian@0 353 * in the various files.
ian@0 354 * Second pass generate the documentation.
ian@0 355 * This is required because function are declared
ian@0 356 * and exported in different files :-((
ian@0 357 */
ian@0 358 /* Collect symbols */
ian@0 359 defaultline = noaction;
ian@0 360 internalfunctions = find_export_symbols;
ian@0 361 externalfunctions = find_export_symbols;
ian@0 362 symbolsonly = find_export_symbols;
ian@0 363 singlefunctions = noaction2;
ian@0 364 parse_file(infile);
ian@0 365
ian@0 366 /* Rewind to start from beginning of file again */
ian@0 367 fseek(infile, 0, SEEK_SET);
ian@0 368 defaultline = printline;
ian@0 369 internalfunctions = intfunc;
ian@0 370 externalfunctions = extfunc;
ian@0 371 symbolsonly = printline;
ian@0 372 singlefunctions = singfunc;
ian@0 373
ian@0 374 parse_file(infile);
ian@0 375 }
ian@0 376 else if (strcmp("depend", argv[1]) == 0)
ian@0 377 {
ian@0 378 /* Create first part of dependency chain
ian@0 379 * file.tmpl */
ian@0 380 printf("%s\t", argv[2]);
ian@0 381 defaultline = noaction;
ian@0 382 internalfunctions = adddep;
ian@0 383 externalfunctions = adddep;
ian@0 384 symbolsonly = adddep;
ian@0 385 singlefunctions = adddep2;
ian@0 386 parse_file(infile);
ian@0 387 printf("\n");
ian@0 388 }
ian@0 389 else
ian@0 390 {
ian@0 391 fprintf(stderr, "Unknown option: %s\n", argv[1]);
ian@0 392 exit(1);
ian@0 393 }
ian@0 394 fclose(infile);
ian@0 395 fflush(stdout);
ian@0 396 return exitstatus;
ian@0 397 }
ian@0 398