ia64/linux-2.6.18-xen.hg

view scripts/conmakehash.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 * conmakehash.c
3 *
4 * Create arrays for initializing the kernel folded tables (using a hash
5 * table turned out to be to limiting...) Unfortunately we can't simply
6 * preinitialize the tables at compile time since kfree() cannot accept
7 * memory not allocated by kmalloc(), and doing our own memory management
8 * just for this seems like massive overkill.
9 *
10 * Copyright (C) 1995-1997 H. Peter Anvin
11 *
12 * This program is a part of the Linux kernel, and may be freely
13 * copied under the terms of the GNU General Public License (GPL),
14 * version 2, or at your option any later version.
15 */
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <sysexits.h>
20 #include <string.h>
21 #include <ctype.h>
23 #define MAX_FONTLEN 256
25 typedef unsigned short unicode;
27 void usage(char *argv0)
28 {
29 fprintf(stderr, "Usage: \n"
30 " %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
31 exit(EX_USAGE);
32 }
34 int getunicode(char **p0)
35 {
36 char *p = *p0;
38 while (*p == ' ' || *p == '\t')
39 p++;
40 if (*p != 'U' || p[1] != '+' ||
41 !isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
42 !isxdigit(p[5]) || isxdigit(p[6]))
43 return -1;
44 *p0 = p+6;
45 return strtol(p+2,0,16);
46 }
48 unicode unitable[MAX_FONTLEN][255];
49 /* Massive overkill, but who cares? */
50 int unicount[MAX_FONTLEN];
52 void addpair(int fp, int un)
53 {
54 int i;
56 if ( un <= 0xfffe )
57 {
58 /* Check it isn't a duplicate */
60 for ( i = 0 ; i < unicount[fp] ; i++ )
61 if ( unitable[fp][i] == un )
62 return;
64 /* Add to list */
66 if ( unicount[fp] > 254 )
67 {
68 fprintf(stderr, "ERROR: Only 255 unicodes/glyph permitted!\n");
69 exit(EX_DATAERR);
70 }
72 unitable[fp][unicount[fp]] = un;
73 unicount[fp]++;
74 }
76 /* otherwise: ignore */
77 }
79 int main(int argc, char *argv[])
80 {
81 FILE *ctbl;
82 char *tblname;
83 char buffer[65536];
84 int fontlen;
85 int i, nuni, nent;
86 int fp0, fp1, un0, un1;
87 char *p, *p1;
89 if ( argc < 2 || argc > 5 )
90 usage(argv[0]);
92 if ( !strcmp(argv[1],"-") )
93 {
94 ctbl = stdin;
95 tblname = "stdin";
96 }
97 else
98 {
99 ctbl = fopen(tblname = argv[1], "r");
100 if ( !ctbl )
101 {
102 perror(tblname);
103 exit(EX_NOINPUT);
104 }
105 }
107 /* For now we assume the default font is always 256 characters. */
108 fontlen = 256;
110 /* Initialize table */
112 for ( i = 0 ; i < fontlen ; i++ )
113 unicount[i] = 0;
115 /* Now we come to the tricky part. Parse the input table. */
117 while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
118 {
119 if ( (p = strchr(buffer, '\n')) != NULL )
120 *p = '\0';
121 else
122 fprintf(stderr, "%s: Warning: line too long\n", tblname);
124 p = buffer;
126 /*
127 * Syntax accepted:
128 * <fontpos> <unicode> <unicode> ...
129 * <range> idem
130 * <range> <unicode range>
131 *
132 * where <range> ::= <fontpos>-<fontpos>
133 * and <unicode> ::= U+<h><h><h><h>
134 * and <h> ::= <hexadecimal digit>
135 */
137 while (*p == ' ' || *p == '\t')
138 p++;
139 if (!*p || *p == '#')
140 continue; /* skip comment or blank line */
142 fp0 = strtol(p, &p1, 0);
143 if (p1 == p)
144 {
145 fprintf(stderr, "Bad input line: %s\n", buffer);
146 exit(EX_DATAERR);
147 }
148 p = p1;
150 while (*p == ' ' || *p == '\t')
151 p++;
152 if (*p == '-')
153 {
154 p++;
155 fp1 = strtol(p, &p1, 0);
156 if (p1 == p)
157 {
158 fprintf(stderr, "Bad input line: %s\n", buffer);
159 exit(EX_DATAERR);
160 }
161 p = p1;
162 }
163 else
164 fp1 = 0;
166 if ( fp0 < 0 || fp0 >= fontlen )
167 {
168 fprintf(stderr,
169 "%s: Glyph number (0x%x) larger than font length\n",
170 tblname, fp0);
171 exit(EX_DATAERR);
172 }
173 if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
174 {
175 fprintf(stderr,
176 "%s: Bad end of range (0x%x)\n",
177 tblname, fp1);
178 exit(EX_DATAERR);
179 }
181 if (fp1)
182 {
183 /* we have a range; expect the word "idem" or a Unicode range of the
184 same length */
185 while (*p == ' ' || *p == '\t')
186 p++;
187 if (!strncmp(p, "idem", 4))
188 {
189 for (i=fp0; i<=fp1; i++)
190 addpair(i,i);
191 p += 4;
192 }
193 else
194 {
195 un0 = getunicode(&p);
196 while (*p == ' ' || *p == '\t')
197 p++;
198 if (*p != '-')
199 {
200 fprintf(stderr,
201 "%s: Corresponding to a range of font positions, there should be a Unicode range\n",
202 tblname);
203 exit(EX_DATAERR);
204 }
205 p++;
206 un1 = getunicode(&p);
207 if (un0 < 0 || un1 < 0)
208 {
209 fprintf(stderr,
210 "%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
211 tblname, fp0, fp1);
212 exit(EX_DATAERR);
213 }
214 if (un1 - un0 != fp1 - fp0)
215 {
216 fprintf(stderr,
217 "%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
218 tblname, un0, un1, fp0, fp1);
219 exit(EX_DATAERR);
220 }
221 for(i=fp0; i<=fp1; i++)
222 addpair(i,un0-fp0+i);
223 }
224 }
225 else
226 {
227 /* no range; expect a list of unicode values for a single font position */
229 while ( (un0 = getunicode(&p)) >= 0 )
230 addpair(fp0, un0);
231 }
232 while (*p == ' ' || *p == '\t')
233 p++;
234 if (*p && *p != '#')
235 fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
236 }
238 /* Okay, we hit EOF, now output hash table */
240 fclose(ctbl);
243 /* Compute total size of Unicode list */
244 nuni = 0;
245 for ( i = 0 ; i < fontlen ; i++ )
246 nuni += unicount[i];
248 printf("\
249 /*\n\
250 * Do not edit this file; it was automatically generated by\n\
251 *\n\
252 * conmakehash %s > [this file]\n\
253 *\n\
254 */\n\
255 \n\
256 #include <linux/types.h>\n\
257 \n\
258 u8 dfont_unicount[%d] = \n\
259 {\n\t", argv[1], fontlen);
261 for ( i = 0 ; i < fontlen ; i++ )
262 {
263 printf("%3d", unicount[i]);
264 if ( i == fontlen-1 )
265 printf("\n};\n");
266 else if ( i % 8 == 7 )
267 printf(",\n\t");
268 else
269 printf(", ");
270 }
272 printf("\nu16 dfont_unitable[%d] = \n{\n\t", nuni);
274 fp0 = 0;
275 nent = 0;
276 for ( i = 0 ; i < nuni ; i++ )
277 {
278 while ( nent >= unicount[fp0] )
279 {
280 fp0++;
281 nent = 0;
282 }
283 printf("0x%04x", unitable[fp0][nent++]);
284 if ( i == nuni-1 )
285 printf("\n};\n");
286 else if ( i % 8 == 7 )
287 printf(",\n\t");
288 else
289 printf(", ");
290 }
292 exit(EX_OK);
293 }