ia64/linux-2.6.18-xen.hg

view arch/mips/basler/excite/excite_device.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 by Basler Vision Technologies AG
3 * Author: Thomas Koeller <thomas.koeller@baslerweb.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
20 #include <linux/kernel.h>
21 #include <linux/init.h>
22 #include <linux/platform_device.h>
23 #include <linux/ioport.h>
24 #include <linux/err.h>
25 #include <linux/jiffies.h>
26 #include <linux/sched.h>
27 #include <asm/types.h>
28 #include <asm/rm9k-ocd.h>
30 #include <excite.h>
31 #include <rm9k_eth.h>
32 #include <rm9k_wdt.h>
33 #include <rm9k_xicap.h>
34 #include <excite_nandflash.h>
36 #include "excite_iodev.h"
38 #define RM9K_GE_UNIT 0
39 #define XICAP_UNIT 0
40 #define NAND_UNIT 0
42 #define DLL_TIMEOUT 3 /* seconds */
45 #define RINIT(__start__, __end__, __name__, __parent__) { \
46 .name = __name__ "_0", \
47 .start = (__start__), \
48 .end = (__end__), \
49 .flags = 0, \
50 .parent = (__parent__) \
51 }
53 #define RINIT_IRQ(__irq__, __name__) { \
54 .name = __name__ "_0", \
55 .start = (__irq__), \
56 .end = (__irq__), \
57 .flags = IORESOURCE_IRQ, \
58 .parent = NULL \
59 }
63 enum {
64 slice_xicap,
65 slice_eth
66 };
70 static struct resource
71 excite_ctr_resource = {
72 .name = "GPI counters",
73 .start = 0,
74 .end = 5,
75 .flags = 0,
76 .parent = NULL,
77 .sibling = NULL,
78 .child = NULL
79 },
80 excite_gpislice_resource = {
81 .name = "GPI slices",
82 .start = 0,
83 .end = 1,
84 .flags = 0,
85 .parent = NULL,
86 .sibling = NULL,
87 .child = NULL
88 },
89 excite_mdio_channel_resource = {
90 .name = "MDIO channels",
91 .start = 0,
92 .end = 1,
93 .flags = 0,
94 .parent = NULL,
95 .sibling = NULL,
96 .child = NULL
97 },
98 excite_fifomem_resource = {
99 .name = "FIFO memory",
100 .start = 0,
101 .end = 767,
102 .flags = 0,
103 .parent = NULL,
104 .sibling = NULL,
105 .child = NULL
106 },
107 excite_scram_resource = {
108 .name = "Scratch RAM",
109 .start = EXCITE_PHYS_SCRAM,
110 .end = EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1,
111 .flags = IORESOURCE_MEM,
112 .parent = NULL,
113 .sibling = NULL,
114 .child = NULL
115 },
116 excite_fpga_resource = {
117 .name = "System FPGA",
118 .start = EXCITE_PHYS_FPGA,
119 .end = EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1,
120 .flags = IORESOURCE_MEM,
121 .parent = NULL,
122 .sibling = NULL,
123 .child = NULL
124 },
125 excite_nand_resource = {
126 .name = "NAND flash control",
127 .start = EXCITE_PHYS_NAND,
128 .end = EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1,
129 .flags = IORESOURCE_MEM,
130 .parent = NULL,
131 .sibling = NULL,
132 .child = NULL
133 },
134 excite_titan_resource = {
135 .name = "TITAN registers",
136 .start = EXCITE_PHYS_TITAN,
137 .end = EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1,
138 .flags = IORESOURCE_MEM,
139 .parent = NULL,
140 .sibling = NULL,
141 .child = NULL
142 };
146 static void adjust_resources(struct resource *res, unsigned int n)
147 {
148 struct resource *p;
149 const unsigned long mask = IORESOURCE_IO | IORESOURCE_MEM
150 | IORESOURCE_IRQ | IORESOURCE_DMA;
152 for (p = res; p < res + n; p++) {
153 const struct resource * const parent = p->parent;
154 if (parent) {
155 p->start += parent->start;
156 p->end += parent->start;
157 p->flags = parent->flags & mask;
158 }
159 }
160 }
164 #if defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE)
165 static struct resource xicap_rsrc[] = {
166 RINIT(0x4840, 0x486f, XICAP_RESOURCE_FIFO_RX, &excite_titan_resource),
167 RINIT(0x4940, 0x494b, XICAP_RESOURCE_FIFO_TX, &excite_titan_resource),
168 RINIT(0x5040, 0x5127, XICAP_RESOURCE_XDMA, &excite_titan_resource),
169 RINIT(0x1000, 0x112f, XICAP_RESOURCE_PKTPROC, &excite_titan_resource),
170 RINIT(0x1100, 0x110f, XICAP_RESOURCE_PKT_STREAM, &excite_fpga_resource),
171 RINIT(0x0800, 0x0bff, XICAP_RESOURCE_DMADESC, &excite_scram_resource),
172 RINIT(slice_xicap, slice_xicap, XICAP_RESOURCE_GPI_SLICE, &excite_gpislice_resource),
173 RINIT(0x0100, 0x02ff, XICAP_RESOURCE_FIFO_BLK, &excite_fifomem_resource),
174 RINIT_IRQ(TITAN_IRQ, XICAP_RESOURCE_IRQ)
175 };
177 static struct platform_device xicap_pdev = {
178 .name = XICAP_NAME,
179 .id = XICAP_UNIT,
180 .num_resources = ARRAY_SIZE(xicap_rsrc),
181 .resource = xicap_rsrc
182 };
184 /*
185 * Create a platform device for the GPI port that receives the
186 * image data from the embedded camera.
187 */
188 static int __init xicap_devinit(void)
189 {
190 unsigned long tend;
191 u32 reg;
192 int retval;
194 adjust_resources(xicap_rsrc, ARRAY_SIZE(xicap_rsrc));
196 /* Power up the slice and configure it. */
197 reg = titan_readl(CPTC1R);
198 reg &= ~(0x11100 << slice_xicap);
199 titan_writel(reg, CPTC1R);
201 /* Enable slice & DLL. */
202 reg= titan_readl(CPRR);
203 reg &= ~(0x00030003 << (slice_xicap * 2));
204 titan_writel(reg, CPRR);
206 /* Wait for DLLs to lock */
207 tend = jiffies + DLL_TIMEOUT * HZ;
208 while (time_before(jiffies, tend)) {
209 if (!(~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4))))
210 break;
211 yield();
212 }
214 if (~titan_readl(CPDSR) & (0x1 << (slice_xicap * 4))) {
215 printk(KERN_ERR "%s: DLL not locked after %u seconds\n",
216 xicap_pdev.name, DLL_TIMEOUT);
217 retval = -ETIME;
218 } else {
219 /* Register platform device */
220 retval = platform_device_register(&xicap_pdev);
221 }
223 return retval;
224 }
226 device_initcall(xicap_devinit);
227 #endif /* defined(CONFIG_EXCITE_FCAP_GPI) || defined(CONFIG_EXCITE_FCAP_GPI_MODULE) */
231 #if defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE)
232 static struct resource wdt_rsrc[] = {
233 RINIT(0, 0, WDT_RESOURCE_COUNTER, &excite_ctr_resource),
234 RINIT(0x0084, 0x008f, WDT_RESOURCE_REGS, &excite_titan_resource),
235 RINIT_IRQ(TITAN_IRQ, WDT_RESOURCE_IRQ)
236 };
238 static struct platform_device wdt_pdev = {
239 .name = WDT_NAME,
240 .id = -1,
241 .num_resources = ARRAY_SIZE(wdt_rsrc),
242 .resource = wdt_rsrc
243 };
245 /*
246 * Create a platform device for the GPI port that receives the
247 * image data from the embedded camera.
248 */
249 static int __init wdt_devinit(void)
250 {
251 adjust_resources(wdt_rsrc, ARRAY_SIZE(wdt_rsrc));
252 return platform_device_register(&wdt_pdev);
253 }
255 device_initcall(wdt_devinit);
256 #endif /* defined(CONFIG_WDT_RM9K_GPI) || defined(CONFIG_WDT_RM9K_GPI_MODULE) */
260 static struct resource excite_nandflash_rsrc[] = {
261 RINIT(0x2000, 0x201f, EXCITE_NANDFLASH_RESOURCE_REGS, &excite_nand_resource)
262 };
264 static struct platform_device excite_nandflash_pdev = {
265 .name = "excite_nand",
266 .id = NAND_UNIT,
267 .num_resources = ARRAY_SIZE(excite_nandflash_rsrc),
268 .resource = excite_nandflash_rsrc
269 };
271 /*
272 * Create a platform device for the access to the nand-flash
273 * port
274 */
275 static int __init excite_nandflash_devinit(void)
276 {
277 adjust_resources(excite_nandflash_rsrc, ARRAY_SIZE(excite_nandflash_rsrc));
279 /* nothing to be done here */
281 /* Register platform device */
282 return platform_device_register(&excite_nandflash_pdev);
283 }
285 device_initcall(excite_nandflash_devinit);
289 static struct resource iodev_rsrc[] = {
290 RINIT_IRQ(FPGA1_IRQ, IODEV_RESOURCE_IRQ)
291 };
293 static struct platform_device io_pdev = {
294 .name = IODEV_NAME,
295 .id = -1,
296 .num_resources = ARRAY_SIZE(iodev_rsrc),
297 .resource = iodev_rsrc
298 };
300 /*
301 * Create a platform device for the external I/O ports.
302 */
303 static int __init io_devinit(void)
304 {
305 adjust_resources(iodev_rsrc, ARRAY_SIZE(iodev_rsrc));
306 return platform_device_register(&io_pdev);
307 }
309 device_initcall(io_devinit);
314 #if defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE)
315 static struct resource rm9k_ge_rsrc[] = {
316 RINIT(0x2200, 0x27ff, RM9K_GE_RESOURCE_MAC, &excite_titan_resource),
317 RINIT(0x1800, 0x1fff, RM9K_GE_RESOURCE_MSTAT, &excite_titan_resource),
318 RINIT(0x2000, 0x212f, RM9K_GE_RESOURCE_PKTPROC, &excite_titan_resource),
319 RINIT(0x5140, 0x5227, RM9K_GE_RESOURCE_XDMA, &excite_titan_resource),
320 RINIT(0x4870, 0x489f, RM9K_GE_RESOURCE_FIFO_RX, &excite_titan_resource),
321 RINIT(0x494c, 0x4957, RM9K_GE_RESOURCE_FIFO_TX, &excite_titan_resource),
322 RINIT(0x0000, 0x007f, RM9K_GE_RESOURCE_FIFOMEM_RX, &excite_fifomem_resource),
323 RINIT(0x0080, 0x00ff, RM9K_GE_RESOURCE_FIFOMEM_TX, &excite_fifomem_resource),
324 RINIT(0x0180, 0x019f, RM9K_GE_RESOURCE_PHY, &excite_titan_resource),
325 RINIT(0x0000, 0x03ff, RM9K_GE_RESOURCE_DMADESC_RX, &excite_scram_resource),
326 RINIT(0x0400, 0x07ff, RM9K_GE_RESOURCE_DMADESC_TX, &excite_scram_resource),
327 RINIT(slice_eth, slice_eth, RM9K_GE_RESOURCE_GPI_SLICE, &excite_gpislice_resource),
328 RINIT(0, 0, RM9K_GE_RESOURCE_MDIO_CHANNEL, &excite_mdio_channel_resource),
329 RINIT_IRQ(TITAN_IRQ, RM9K_GE_RESOURCE_IRQ_MAIN),
330 RINIT_IRQ(PHY_IRQ, RM9K_GE_RESOURCE_IRQ_PHY)
331 };
333 static struct platform_device rm9k_ge_pdev = {
334 .name = RM9K_GE_NAME,
335 .id = RM9K_GE_UNIT,
336 .num_resources = ARRAY_SIZE(rm9k_ge_rsrc),
337 .resource = rm9k_ge_rsrc
338 };
342 /*
343 * Create a platform device for the Ethernet port.
344 */
345 static int __init rm9k_ge_devinit(void)
346 {
347 u32 reg;
349 adjust_resources(rm9k_ge_rsrc, ARRAY_SIZE(rm9k_ge_rsrc));
351 /* Power up the slice and configure it. */
352 reg = titan_readl(CPTC1R);
353 reg &= ~(0x11000 << slice_eth);
354 reg |= 0x100 << slice_eth;
355 titan_writel(reg, CPTC1R);
357 /* Take the MAC out of reset, reset the DLLs. */
358 reg = titan_readl(CPRR);
359 reg &= ~(0x00030000 << (slice_eth * 2));
360 reg |= 0x3 << (slice_eth * 2);
361 titan_writel(reg, CPRR);
363 return platform_device_register(&rm9k_ge_pdev);
364 }
366 device_initcall(rm9k_ge_devinit);
367 #endif /* defined(CONFIG_RM9K_GE) || defined(CONFIG_RM9K_GE_MODULE) */
371 static int __init excite_setup_devs(void)
372 {
373 int res;
374 u32 reg;
376 /* Enable xdma and fifo interrupts */
377 reg = titan_readl(0x0050);
378 titan_writel(reg | 0x18000000, 0x0050);
380 res = request_resource(&iomem_resource, &excite_titan_resource);
381 if (res)
382 return res;
383 res = request_resource(&iomem_resource, &excite_scram_resource);
384 if (res)
385 return res;
386 res = request_resource(&iomem_resource, &excite_fpga_resource);
387 if (res)
388 return res;
389 res = request_resource(&iomem_resource, &excite_nand_resource);
390 if (res)
391 return res;
392 excite_fpga_resource.flags = excite_fpga_resource.parent->flags &
393 ( IORESOURCE_IO | IORESOURCE_MEM
394 | IORESOURCE_IRQ | IORESOURCE_DMA);
395 excite_nand_resource.flags = excite_nand_resource.parent->flags &
396 ( IORESOURCE_IO | IORESOURCE_MEM
397 | IORESOURCE_IRQ | IORESOURCE_DMA);
399 return 0;
400 }
402 arch_initcall(excite_setup_devs);