ia64/linux-2.6.18-xen.hg

view drivers/serial/8250_early.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 * Early serial console for 8250/16550 devices
3 *
4 * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
5 * Bjorn Helgaas <bjorn.helgaas@hp.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Based on the 8250.c serial driver, Copyright (C) 2001 Russell King,
12 * and on early_printk.c by Andi Kleen.
13 *
14 * This is for use before the serial driver has initialized, in
15 * particular, before the UARTs have been discovered and named.
16 * Instead of specifying the console device as, e.g., "ttyS0",
17 * we locate the device directly by its MMIO or I/O port address.
18 *
19 * The user can specify the device directly, e.g.,
20 * console=uart,io,0x3f8,9600n8
21 * console=uart,mmio,0xff5e0000,115200n8
22 * or platform code can call early_uart_console_init() to set
23 * the early UART device.
24 *
25 * After the normal serial driver starts, we try to locate the
26 * matching ttyS device and start a console there.
27 */
29 #include <linux/tty.h>
30 #include <linux/init.h>
31 #include <linux/console.h>
32 #include <linux/serial_core.h>
33 #include <linux/serial_reg.h>
34 #include <linux/serial.h>
35 #include <asm/io.h>
36 #include <asm/serial.h>
38 struct early_uart_device {
39 struct uart_port port;
40 char options[16]; /* e.g., 115200n8 */
41 unsigned int baud;
42 };
44 static struct early_uart_device early_device __initdata;
45 static int early_uart_registered __initdata;
47 static unsigned int __init serial_in(struct uart_port *port, int offset)
48 {
49 if (port->iotype == UPIO_MEM)
50 return readb(port->membase + offset);
51 else
52 return inb(port->iobase + offset);
53 }
55 static void __init serial_out(struct uart_port *port, int offset, int value)
56 {
57 if (port->iotype == UPIO_MEM)
58 writeb(value, port->membase + offset);
59 else
60 outb(value, port->iobase + offset);
61 }
63 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
65 static void __init wait_for_xmitr(struct uart_port *port)
66 {
67 unsigned int status;
69 for (;;) {
70 status = serial_in(port, UART_LSR);
71 if ((status & BOTH_EMPTY) == BOTH_EMPTY)
72 return;
73 cpu_relax();
74 }
75 }
77 static void __init putc(struct uart_port *port, int c)
78 {
79 wait_for_xmitr(port);
80 serial_out(port, UART_TX, c);
81 }
83 static void __init early_uart_write(struct console *console, const char *s, unsigned int count)
84 {
85 struct uart_port *port = &early_device.port;
86 unsigned int ier;
88 /* Save the IER and disable interrupts */
89 ier = serial_in(port, UART_IER);
90 serial_out(port, UART_IER, 0);
92 uart_console_write(port, s, count, putc);
94 /* Wait for transmitter to become empty and restore the IER */
95 wait_for_xmitr(port);
96 serial_out(port, UART_IER, ier);
97 }
99 static unsigned int __init probe_baud(struct uart_port *port)
100 {
101 unsigned char lcr, dll, dlm;
102 unsigned int quot;
104 lcr = serial_in(port, UART_LCR);
105 serial_out(port, UART_LCR, lcr | UART_LCR_DLAB);
106 dll = serial_in(port, UART_DLL);
107 dlm = serial_in(port, UART_DLM);
108 serial_out(port, UART_LCR, lcr);
110 quot = (dlm << 8) | dll;
111 return (port->uartclk / 16) / quot;
112 }
114 static void __init init_port(struct early_uart_device *device)
115 {
116 struct uart_port *port = &device->port;
117 unsigned int divisor;
118 unsigned char c;
120 serial_out(port, UART_LCR, 0x3); /* 8n1 */
121 serial_out(port, UART_IER, 0); /* no interrupt */
122 serial_out(port, UART_FCR, 0); /* no fifo */
123 serial_out(port, UART_MCR, 0x3); /* DTR + RTS */
125 divisor = port->uartclk / (16 * device->baud);
126 c = serial_in(port, UART_LCR);
127 serial_out(port, UART_LCR, c | UART_LCR_DLAB);
128 serial_out(port, UART_DLL, divisor & 0xff);
129 serial_out(port, UART_DLM, (divisor >> 8) & 0xff);
130 serial_out(port, UART_LCR, c & ~UART_LCR_DLAB);
131 }
133 static int __init parse_options(struct early_uart_device *device, char *options)
134 {
135 struct uart_port *port = &device->port;
136 int mapsize = 64;
137 int mmio, length;
139 if (!options)
140 return -ENODEV;
142 port->uartclk = BASE_BAUD * 16;
143 if (!strncmp(options, "mmio,", 5)) {
144 port->iotype = UPIO_MEM;
145 port->mapbase = simple_strtoul(options + 5, &options, 0);
146 port->membase = ioremap(port->mapbase, mapsize);
147 if (!port->membase) {
148 printk(KERN_ERR "%s: Couldn't ioremap 0x%lx\n",
149 __FUNCTION__, port->mapbase);
150 return -ENOMEM;
151 }
152 mmio = 1;
153 } else if (!strncmp(options, "io,", 3)) {
154 port->iotype = UPIO_PORT;
155 port->iobase = simple_strtoul(options + 3, &options, 0);
156 mmio = 0;
157 } else
158 return -EINVAL;
160 if ((options = strchr(options, ','))) {
161 options++;
162 device->baud = simple_strtoul(options, NULL, 0);
163 length = min(strcspn(options, " "), sizeof(device->options));
164 strncpy(device->options, options, length);
165 } else {
166 device->baud = probe_baud(port);
167 snprintf(device->options, sizeof(device->options), "%u",
168 device->baud);
169 }
171 printk(KERN_INFO "Early serial console at %s 0x%lx (options '%s')\n",
172 mmio ? "MMIO" : "I/O port",
173 mmio ? port->mapbase : (unsigned long) port->iobase,
174 device->options);
175 return 0;
176 }
178 static int __init early_uart_setup(struct console *console, char *options)
179 {
180 struct early_uart_device *device = &early_device;
181 int err;
183 if (device->port.membase || device->port.iobase)
184 return 0;
186 if ((err = parse_options(device, options)) < 0)
187 return err;
189 init_port(device);
190 return 0;
191 }
193 static struct console early_uart_console __initdata = {
194 .name = "uart",
195 .write = early_uart_write,
196 .setup = early_uart_setup,
197 .flags = CON_PRINTBUFFER,
198 .index = -1,
199 };
201 static int __init early_uart_console_init(void)
202 {
203 if (!early_uart_registered) {
204 register_console(&early_uart_console);
205 early_uart_registered = 1;
206 }
207 return 0;
208 }
209 console_initcall(early_uart_console_init);
211 int __init early_serial_console_init(char *cmdline)
212 {
213 char *options;
214 int err;
216 options = strstr(cmdline, "console=uart,");
217 if (!options)
218 return -ENODEV;
220 options = strchr(cmdline, ',') + 1;
221 if ((err = early_uart_setup(NULL, options)) < 0)
222 return err;
223 return early_uart_console_init();
224 }
226 static int __init early_uart_console_switch(void)
227 {
228 struct early_uart_device *device = &early_device;
229 struct uart_port *port = &device->port;
230 int mmio, line;
232 if (!(early_uart_console.flags & CON_ENABLED))
233 return 0;
235 /* Try to start the normal driver on a matching line. */
236 mmio = (port->iotype == UPIO_MEM);
237 line = serial8250_start_console(port, device->options);
238 if (line < 0)
239 printk("No ttyS device at %s 0x%lx for console\n",
240 mmio ? "MMIO" : "I/O port",
241 mmio ? port->mapbase :
242 (unsigned long) port->iobase);
244 unregister_console(&early_uart_console);
245 if (mmio)
246 iounmap(port->membase);
248 return 0;
249 }
250 late_initcall(early_uart_console_switch);