ia64/linux-2.6.18-xen.hg

view arch/mips/basler/excite/excite_setup.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 * Copyright (C) 2004, 2005 by Basler Vision Technologies AG
3 * Author: Thomas Koeller <thomas.koeller@baslerweb.com>
4 * Based on the PMC-Sierra Yosemite board support by Ralf Baechle and
5 * Manish Lachwani.
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
22 #include <linux/types.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/string.h>
26 #include <linux/tty.h>
27 #include <linux/serial_core.h>
28 #include <linux/serial.h>
29 #include <linux/ioport.h>
30 #include <linux/spinlock.h>
31 #include <asm/bootinfo.h>
32 #include <asm/mipsregs.h>
33 #include <asm/pgtable-32.h>
34 #include <asm/io.h>
35 #include <asm/time.h>
36 #include <asm/rm9k-ocd.h>
38 #include <excite.h>
40 #define TITAN_UART_CLK 25000000
42 #if 1
43 /* normal serial port assignment */
44 #define REGBASE_SER0 0x0208
45 #define REGBASE_SER1 0x0238
46 #define MASK_SER0 0x1
47 #define MASK_SER1 0x2
48 #else
49 /* serial ports swapped */
50 #define REGBASE_SER0 0x0238
51 #define REGBASE_SER1 0x0208
52 #define MASK_SER0 0x2
53 #define MASK_SER1 0x1
54 #endif
56 unsigned long memsize;
57 char modetty[30];
58 unsigned int titan_irq = TITAN_IRQ;
59 static void __iomem * ctl_regs;
60 u32 unit_id;
62 volatile void __iomem * const ocd_base = (void *) (EXCITE_ADDR_OCD);
63 volatile void __iomem * const titan_base = (void *) (EXCITE_ADDR_TITAN);
65 /* Protect access to shared GPI registers */
66 spinlock_t titan_lock = SPIN_LOCK_UNLOCKED;
67 int titan_irqflags;
70 static void excite_timer_init(void)
71 {
72 const u32 modebit5 = ocd_readl(0x00e4);
73 unsigned int
74 mult = ((modebit5 >> 11) & 0x1f) + 2,
75 div = ((modebit5 >> 16) & 0x1f) + 2;
77 if (div == 33) div = 1;
78 mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2;
79 }
81 void __init plat_timer_setup(struct irqaction *irq)
82 {
83 /* The eXcite platform uses the alternate timer interrupt */
84 set_c0_intcontrol(0x80);
85 setup_irq(TIMER_IRQ, irq);
86 }
88 static int __init excite_init_console(void)
89 {
90 #if defined(CONFIG_SERIAL_8250)
91 static __initdata char serr[] =
92 KERN_ERR "Serial port #%u setup failed\n";
93 struct uart_port up;
95 /* Take the DUART out of reset */
96 titan_writel(0x00ff1cff, CPRR);
98 #if defined(CONFIG_KGDB) || (CONFIG_SERIAL_8250_NR_UARTS > 1)
99 /* Enable both ports */
100 titan_writel(MASK_SER0 | MASK_SER1, UACFG);
101 #else
102 /* Enable port #0 only */
103 titan_writel(MASK_SER0, UACFG);
104 #endif /* defined(CONFIG_KGDB) */
106 /*
107 * Set up serial port #0. Do not use autodetection; the result is
108 * not what we want.
109 */
110 memset(&up, 0, sizeof(up));
111 up.membase = (char *) titan_addr(REGBASE_SER0);
112 up.irq = TITAN_IRQ;
113 up.uartclk = TITAN_UART_CLK;
114 up.regshift = 0;
115 up.iotype = UPIO_MEM32;
116 up.type = PORT_RM9000;
117 up.flags = UPF_SHARE_IRQ;
118 up.line = 0;
119 if (early_serial_setup(&up))
120 printk(serr, up.line);
122 #if CONFIG_SERIAL_8250_NR_UARTS > 1
123 /* And now for port #1. */
124 up.membase = (char *) titan_addr(REGBASE_SER1);
125 up.line = 1;
126 if (early_serial_setup(&up))
127 printk(serr, up.line);
128 #endif /* CONFIG_SERIAL_8250_NR_UARTS > 1 */
129 #else
130 /* Leave the DUART in reset */
131 titan_writel(0x00ff3cff, CPRR);
132 #endif /* defined(CONFIG_SERIAL_8250) */
134 return 0;
135 }
137 static int __init excite_platform_init(void)
138 {
139 unsigned int i;
140 unsigned char buf[3];
141 u8 reg;
142 void __iomem * dpr;
144 /* BIU buffer allocations */
145 ocd_writel(8, CPURSLMT); /* CPU */
146 titan_writel(4, CPGRWL); /* GPI / Ethernet */
148 /* Map control registers located in FPGA */
149 ctl_regs = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_SYSCTL, 16);
150 if (!ctl_regs)
151 panic("eXcite: failed to map platform control registers\n");
152 memcpy_fromio(buf, ctl_regs + 2, ARRAY_SIZE(buf));
153 unit_id = buf[0] | (buf[1] << 8) | (buf[2] << 16);
155 /* Clear the reboot flag */
156 dpr = ioremap_nocache(EXCITE_PHYS_FPGA + EXCITE_FPGA_DPR, 1);
157 reg = __raw_readb(dpr);
158 __raw_writeb(reg & 0x7f, dpr);
159 iounmap(dpr);
161 /* Interrupt controller setup */
162 for (i = INTP0Status0; i < INTP0Status0 + 0x80; i += 0x10) {
163 ocd_writel(0x00000000, i + 0x04);
164 ocd_writel(0xffffffff, i + 0x0c);
165 }
166 ocd_writel(0x2, NMICONFIG);
168 ocd_writel(0x1 << (TITAN_MSGINT % 0x20),
169 INTP0Mask0 + (0x10 * (TITAN_MSGINT / 0x20)));
170 ocd_writel((0x1 << (FPGA0_MSGINT % 0x20))
171 | ocd_readl(INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20))),
172 INTP0Mask0 + (0x10 * (FPGA0_MSGINT / 0x20)));
173 ocd_writel((0x1 << (FPGA1_MSGINT % 0x20))
174 | ocd_readl(INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20))),
175 INTP0Mask0 + (0x10 * (FPGA1_MSGINT / 0x20)));
176 ocd_writel((0x1 << (PHY_MSGINT % 0x20))
177 | ocd_readl(INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20))),
178 INTP0Mask0 + (0x10 * (PHY_MSGINT / 0x20)));
179 #if USB_IRQ < 10
180 ocd_writel((0x1 << (USB_MSGINT % 0x20))
181 | ocd_readl(INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20))),
182 INTP0Mask0 + (0x10 * (USB_MSGINT / 0x20)));
183 #endif
184 /* Enable the packet FIFO, XDMA and XDMA arbiter */
185 titan_writel(0x00ff18ff, CPRR);
187 /*
188 * Set up the PADMUX. Power down all ethernet slices,
189 * they will be powered up and configured at device startup.
190 */
191 titan_writel(0x00878206, CPTC1R);
192 titan_writel(0x00001100, CPTC0R); /* latch PADMUX, enable WCIMODE */
194 /* Reset and enable the FIFO block */
195 titan_writel(0x00000001, SDRXFCIE);
196 titan_writel(0x00000001, SDTXFCIE);
197 titan_writel(0x00000100, SDRXFCIE);
198 titan_writel(0x00000000, SDTXFCIE);
200 /*
201 * Initialize the common interrupt shared by all components of
202 * the GPI/Ethernet subsystem.
203 */
204 titan_writel((EXCITE_PHYS_OCD >> 12), CPCFG0);
205 titan_writel(TITAN_MSGINT, CPCFG1);
207 /*
208 * XDMA configuration.
209 * In order for the XDMA to be sharable among multiple drivers,
210 * the setup must be done here in the platform. The reason is that
211 * this setup can only be done while the XDMA is in reset. If this
212 * were done in a driver, it would interrupt all other drivers
213 * using the XDMA.
214 */
215 titan_writel(0x80021dff, GXCFG); /* XDMA reset */
216 titan_writel(0x00000000, CPXCISRA);
217 titan_writel(0x00000000, CPXCISRB); /* clear pending interrupts */
218 #if defined (CONFIG_HIGHMEM)
219 # error change for HIGHMEM support!
220 #else
221 titan_writel(0x00000000, GXDMADRPFX); /* buffer address prefix */
222 #endif
223 titan_writel(0, GXDMA_DESCADR);
225 for (i = 0x5040; i <= 0x5300; i += 0x0040)
226 titan_writel(0x80080000, i); /* reset channel */
228 titan_writel((0x1 << 29) /* no sparse tx descr. */
229 | (0x1 << 28) /* no sparse rx descr. */
230 | (0x1 << 23) | (0x1 << 24) /* descriptor coherency */
231 | (0x1 << 21) | (0x1 << 22) /* data coherency */
232 | (0x1 << 17)
233 | 0x1dff,
234 GXCFG);
236 #if defined(CONFIG_SMP)
237 # error No SMP support
238 #else
239 /* All interrupts go to core #0 only. */
240 titan_writel(0x1f007fff, CPDST0A);
241 titan_writel(0x00000000, CPDST0B);
242 titan_writel(0x0000ff3f, CPDST1A);
243 titan_writel(0x00000000, CPDST1B);
244 titan_writel(0x00ffffff, CPXDSTA);
245 titan_writel(0x00000000, CPXDSTB);
246 #endif
248 /* Enable DUART interrupts, disable everything else. */
249 titan_writel(0x04000000, CPGIG0ER);
250 titan_writel(0x000000c0, CPGIG1ER);
252 excite_procfs_init();
253 return 0;
254 }
256 void __init plat_mem_setup(void)
257 {
258 volatile u32 * const boot_ocd_base = (u32 *) 0xbf7fc000;
260 /* Announce RAM to system */
261 add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
263 /* Set up timer initialization hooks */
264 board_time_init = excite_timer_init;
266 /* Set up the peripheral address map */
267 *(boot_ocd_base + (LKB9 / sizeof (u32))) = 0;
268 *(boot_ocd_base + (LKB10 / sizeof (u32))) = 0;
269 *(boot_ocd_base + (LKB11 / sizeof (u32))) = 0;
270 *(boot_ocd_base + (LKB12 / sizeof (u32))) = 0;
271 wmb();
272 *(boot_ocd_base + (LKB0 / sizeof (u32))) = EXCITE_PHYS_OCD >> 4;
273 wmb();
275 ocd_writel((EXCITE_PHYS_TITAN >> 4) | 0x1UL, LKB5);
276 ocd_writel(((EXCITE_SIZE_TITAN >> 4) & 0x7fffff00) - 0x100, LKM5);
277 ocd_writel((EXCITE_PHYS_SCRAM >> 4) | 0x1UL, LKB13);
278 ocd_writel(((EXCITE_SIZE_SCRAM >> 4) & 0xffffff00) - 0x100, LKM13);
280 /* Local bus slot #0 */
281 ocd_writel(0x00040510, LDP0);
282 ocd_writel((EXCITE_PHYS_BOOTROM >> 4) | 0x1UL, LKB9);
283 ocd_writel(((EXCITE_SIZE_BOOTROM >> 4) & 0x03ffff00) - 0x100, LKM9);
285 /* Local bus slot #2 */
286 ocd_writel(0x00000330, LDP2);
287 ocd_writel((EXCITE_PHYS_FPGA >> 4) | 0x1, LKB11);
288 ocd_writel(((EXCITE_SIZE_FPGA >> 4) - 0x100) & 0x03ffff00, LKM11);
290 /* Local bus slot #3 */
291 ocd_writel(0x00123413, LDP3);
292 ocd_writel((EXCITE_PHYS_NAND >> 4) | 0x1, LKB12);
293 ocd_writel(((EXCITE_SIZE_NAND >> 4) - 0x100) & 0x03ffff00, LKM12);
294 }
298 console_initcall(excite_init_console);
299 arch_initcall(excite_platform_init);
301 EXPORT_SYMBOL(titan_lock);
302 EXPORT_SYMBOL(titan_irqflags);
303 EXPORT_SYMBOL(titan_irq);
304 EXPORT_SYMBOL(ocd_base);
305 EXPORT_SYMBOL(titan_base);