ia64/linux-2.6.18-xen.hg

view drivers/serial/suncore.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 /* suncore.c
2 *
3 * Common SUN serial routines. Based entirely
4 * upon drivers/sbus/char/sunserial.c which is:
5 *
6 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
7 *
8 * Adaptation to new UART layer is:
9 *
10 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
11 */
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/console.h>
16 #include <linux/tty.h>
17 #include <linux/errno.h>
18 #include <linux/string.h>
19 #include <linux/init.h>
21 #include <asm/oplib.h>
23 #include "suncore.h"
25 int sunserial_current_minor = 64;
27 EXPORT_SYMBOL(sunserial_current_minor);
29 void
30 sunserial_console_termios(struct console *con)
31 {
32 char mode[16], buf[16], *s;
33 char *mode_prop = "ttyX-mode";
34 char *cd_prop = "ttyX-ignore-cd";
35 char *dtr_prop = "ttyX-rts-dtr-off";
36 char *ssp_console_modes_prop = "ssp-console-modes";
37 int baud, bits, stop, cflag;
38 char parity;
39 int carrier = 0;
40 int rtsdtr = 1;
41 int topnd, nd;
43 if (!serial_console)
44 return;
46 switch (serial_console) {
47 case PROMDEV_OTTYA:
48 mode_prop[3] = 'a';
49 cd_prop[3] = 'a';
50 dtr_prop[3] = 'a';
51 break;
53 case PROMDEV_OTTYB:
54 mode_prop[3] = 'b';
55 cd_prop[3] = 'b';
56 dtr_prop[3] = 'b';
57 break;
59 case PROMDEV_ORSC:
61 nd = prom_pathtoinode("rsc");
62 if (!nd) {
63 strcpy(mode, "115200,8,n,1,-");
64 goto no_options;
65 }
67 if (!prom_node_has_property(nd, ssp_console_modes_prop)) {
68 strcpy(mode, "115200,8,n,1,-");
69 goto no_options;
70 }
72 memset(mode, 0, sizeof(mode));
73 prom_getstring(nd, ssp_console_modes_prop, mode, sizeof(mode));
74 goto no_options;
76 default:
77 strcpy(mode, "9600,8,n,1,-");
78 goto no_options;
79 }
81 topnd = prom_getchild(prom_root_node);
82 nd = prom_searchsiblings(topnd, "options");
83 if (!nd) {
84 strcpy(mode, "9600,8,n,1,-");
85 goto no_options;
86 }
88 if (!prom_node_has_property(nd, mode_prop)) {
89 strcpy(mode, "9600,8,n,1,-");
90 goto no_options;
91 }
93 memset(mode, 0, sizeof(mode));
94 prom_getstring(nd, mode_prop, mode, sizeof(mode));
96 if (prom_node_has_property(nd, cd_prop)) {
97 memset(buf, 0, sizeof(buf));
98 prom_getstring(nd, cd_prop, buf, sizeof(buf));
99 if (!strcmp(buf, "false"))
100 carrier = 1;
102 /* XXX: this is unused below. */
103 }
105 if (prom_node_has_property(nd, dtr_prop)) {
106 memset(buf, 0, sizeof(buf));
107 prom_getstring(nd, dtr_prop, buf, sizeof(buf));
108 if (!strcmp(buf, "false"))
109 rtsdtr = 0;
111 /* XXX: this is unused below. */
112 }
114 no_options:
115 cflag = CREAD | HUPCL | CLOCAL;
117 s = mode;
118 baud = simple_strtoul(s, NULL, 0);
119 s = strchr(s, ',');
120 bits = simple_strtoul(++s, NULL, 0);
121 s = strchr(s, ',');
122 parity = *(++s);
123 s = strchr(s, ',');
124 stop = simple_strtoul(++s, NULL, 0);
125 s = strchr(s, ',');
126 /* XXX handshake is not handled here. */
128 switch (baud) {
129 case 150: cflag |= B150; break;
130 case 300: cflag |= B300; break;
131 case 600: cflag |= B600; break;
132 case 1200: cflag |= B1200; break;
133 case 2400: cflag |= B2400; break;
134 case 4800: cflag |= B4800; break;
135 case 9600: cflag |= B9600; break;
136 case 19200: cflag |= B19200; break;
137 case 38400: cflag |= B38400; break;
138 case 57600: cflag |= B57600; break;
139 case 115200: cflag |= B115200; break;
140 case 230400: cflag |= B230400; break;
141 case 460800: cflag |= B460800; break;
142 default: baud = 9600; cflag |= B9600; break;
143 }
145 switch (bits) {
146 case 5: cflag |= CS5; break;
147 case 6: cflag |= CS6; break;
148 case 7: cflag |= CS7; break;
149 case 8: cflag |= CS8; break;
150 default: cflag |= CS8; break;
151 }
153 switch (parity) {
154 case 'o': cflag |= (PARENB | PARODD); break;
155 case 'e': cflag |= PARENB; break;
156 case 'n': default: break;
157 }
159 switch (stop) {
160 case 2: cflag |= CSTOPB; break;
161 case 1: default: break;
162 }
164 con->cflag = cflag;
165 }
167 EXPORT_SYMBOL(sunserial_console_termios);
169 /* Sun serial MOUSE auto baud rate detection. */
170 static struct mouse_baud_cflag {
171 int baud;
172 unsigned int cflag;
173 } mouse_baud_table[] = {
174 { 1200, B1200 },
175 { 2400, B2400 },
176 { 4800, B4800 },
177 { 9600, B9600 },
178 { -1, ~0 },
179 { -1, ~0 },
180 };
182 unsigned int suncore_mouse_baud_cflag_next(unsigned int cflag, int *new_baud)
183 {
184 int i;
186 for (i = 0; mouse_baud_table[i].baud != -1; i++)
187 if (mouse_baud_table[i].cflag == (cflag & CBAUD))
188 break;
190 i += 1;
191 if (mouse_baud_table[i].baud == -1)
192 i = 0;
194 *new_baud = mouse_baud_table[i].baud;
195 return mouse_baud_table[i].cflag;
196 }
198 EXPORT_SYMBOL(suncore_mouse_baud_cflag_next);
200 /* Basically, when the baud rate is wrong the mouse spits out
201 * breaks to us.
202 */
203 int suncore_mouse_baud_detection(unsigned char ch, int is_break)
204 {
205 static int mouse_got_break = 0;
206 static int ctr = 0;
208 if (is_break) {
209 /* Let a few normal bytes go by before we jump the gun
210 * and say we need to try another baud rate.
211 */
212 if (mouse_got_break && ctr < 8)
213 return 1;
215 /* Ok, we need to try another baud. */
216 ctr = 0;
217 mouse_got_break = 1;
218 return 2;
219 }
220 if (mouse_got_break) {
221 ctr++;
222 if (ch == 0x87) {
223 /* Correct baud rate determined. */
224 mouse_got_break = 0;
225 }
226 return 1;
227 }
228 return 0;
229 }
231 EXPORT_SYMBOL(suncore_mouse_baud_detection);
233 static int __init suncore_init(void)
234 {
235 return 0;
236 }
238 static void __exit suncore_exit(void)
239 {
240 }
242 module_init(suncore_init);
243 module_exit(suncore_exit);
245 MODULE_AUTHOR("Eddie C. Dost, David S. Miller");
246 MODULE_DESCRIPTION("Sun serial common layer");
247 MODULE_LICENSE("GPL");