ia64/linux-2.6.18-xen.hg

view arch/sparc64/kernel/auxio.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 /* auxio.c: Probing for the Sparc AUXIO register at boot time.
2 *
3 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
4 *
5 * Refactoring for unified NCR/PCIO support 2002 Eric Brower (ebrower@usa.net)
6 */
8 #include <linux/config.h>
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/ioport.h>
14 #include <asm/prom.h>
15 #include <asm/of_device.h>
16 #include <asm/io.h>
17 #include <asm/auxio.h>
19 void __iomem *auxio_register = NULL;
20 EXPORT_SYMBOL(auxio_register);
22 enum auxio_type {
23 AUXIO_TYPE_NODEV,
24 AUXIO_TYPE_SBUS,
25 AUXIO_TYPE_EBUS
26 };
28 static enum auxio_type auxio_devtype = AUXIO_TYPE_NODEV;
29 static DEFINE_SPINLOCK(auxio_lock);
31 static void __auxio_sbus_set(u8 bits_on, u8 bits_off)
32 {
33 if (auxio_register) {
34 unsigned char regval;
35 unsigned long flags;
36 unsigned char newval;
38 spin_lock_irqsave(&auxio_lock, flags);
40 regval = sbus_readb(auxio_register);
41 newval = regval | bits_on;
42 newval &= ~bits_off;
43 newval &= ~AUXIO_AUX1_MASK;
44 sbus_writeb(newval, auxio_register);
46 spin_unlock_irqrestore(&auxio_lock, flags);
47 }
48 }
50 static void __auxio_ebus_set(u8 bits_on, u8 bits_off)
51 {
52 if (auxio_register) {
53 unsigned char regval;
54 unsigned long flags;
55 unsigned char newval;
57 spin_lock_irqsave(&auxio_lock, flags);
59 regval = (u8)readl(auxio_register);
60 newval = regval | bits_on;
61 newval &= ~bits_off;
62 writel((u32)newval, auxio_register);
64 spin_unlock_irqrestore(&auxio_lock, flags);
65 }
66 }
68 static inline void __auxio_ebus_set_led(int on)
69 {
70 (on) ? __auxio_ebus_set(AUXIO_PCIO_LED, 0) :
71 __auxio_ebus_set(0, AUXIO_PCIO_LED) ;
72 }
74 static inline void __auxio_sbus_set_led(int on)
75 {
76 (on) ? __auxio_sbus_set(AUXIO_AUX1_LED, 0) :
77 __auxio_sbus_set(0, AUXIO_AUX1_LED) ;
78 }
80 void auxio_set_led(int on)
81 {
82 switch(auxio_devtype) {
83 case AUXIO_TYPE_SBUS:
84 __auxio_sbus_set_led(on);
85 break;
86 case AUXIO_TYPE_EBUS:
87 __auxio_ebus_set_led(on);
88 break;
89 default:
90 break;
91 }
92 }
94 static inline void __auxio_sbus_set_lte(int on)
95 {
96 (on) ? __auxio_sbus_set(AUXIO_AUX1_LTE, 0) :
97 __auxio_sbus_set(0, AUXIO_AUX1_LTE) ;
98 }
100 void auxio_set_lte(int on)
101 {
102 switch(auxio_devtype) {
103 case AUXIO_TYPE_SBUS:
104 __auxio_sbus_set_lte(on);
105 break;
106 case AUXIO_TYPE_EBUS:
107 /* FALL-THROUGH */
108 default:
109 break;
110 }
111 }
113 static struct of_device_id auxio_match[] = {
114 {
115 .name = "auxio",
116 },
117 {},
118 };
120 MODULE_DEVICE_TABLE(of, auxio_match);
122 static int __devinit auxio_probe(struct of_device *dev, const struct of_device_id *match)
123 {
124 struct device_node *dp = dev->node;
125 unsigned long size;
127 if (!strcmp(dp->parent->name, "ebus")) {
128 auxio_devtype = AUXIO_TYPE_EBUS;
129 size = sizeof(u32);
130 } else if (!strcmp(dp->parent->name, "sbus")) {
131 auxio_devtype = AUXIO_TYPE_SBUS;
132 size = 1;
133 } else {
134 printk("auxio: Unknown parent bus type [%s]\n",
135 dp->parent->name);
136 return -ENODEV;
137 }
138 auxio_register = of_ioremap(&dev->resource[0], 0, size, "auxio");
139 if (!auxio_register)
140 return -ENODEV;
142 printk(KERN_INFO "AUXIO: Found device at %s\n",
143 dp->full_name);
145 if (auxio_devtype == AUXIO_TYPE_EBUS)
146 auxio_set_led(AUXIO_LED_ON);
148 return 0;
149 }
151 static struct of_platform_driver auxio_driver = {
152 .name = "auxio",
153 .match_table = auxio_match,
154 .probe = auxio_probe,
155 };
157 static int __init auxio_init(void)
158 {
159 return of_register_driver(&auxio_driver, &of_bus_type);
160 }
162 /* Must be after subsys_initcall() so that busses are probed. Must
163 * be before device_initcall() because things like the floppy driver
164 * need to use the AUXIO register.
165 */
166 fs_initcall(auxio_init);