ia64/linux-2.6.18-xen.hg

view arch/sparc64/kernel/isa.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 #include <linux/kernel.h>
2 #include <linux/init.h>
3 #include <linux/pci.h>
4 #include <linux/slab.h>
5 #include <asm/oplib.h>
6 #include <asm/prom.h>
7 #include <asm/of_device.h>
8 #include <asm/isa.h>
10 struct sparc_isa_bridge *isa_chain;
12 static void __init fatal_err(const char *reason)
13 {
14 prom_printf("ISA: fatal error, %s.\n", reason);
15 }
17 static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
18 {
19 if (child)
20 printk(" (%s)", isa_dev->prom_node->name);
21 else
22 printk(" [%s", isa_dev->prom_node->name);
23 }
25 static struct linux_prom_registers * __init
26 isa_dev_get_resource(struct sparc_isa_device *isa_dev)
27 {
28 struct linux_prom_registers *pregs;
29 unsigned long base, len;
30 int prop_len;
32 pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len);
34 /* Only the first one is interesting. */
35 len = pregs[0].reg_size;
36 base = (((unsigned long)pregs[0].which_io << 32) |
37 (unsigned long)pregs[0].phys_addr);
38 base += isa_dev->bus->parent->io_space.start;
40 isa_dev->resource.start = base;
41 isa_dev->resource.end = (base + len - 1UL);
42 isa_dev->resource.flags = IORESOURCE_IO;
43 isa_dev->resource.name = isa_dev->prom_node->name;
45 request_resource(&isa_dev->bus->parent->io_space,
46 &isa_dev->resource);
48 return pregs;
49 }
51 static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
52 struct linux_prom_registers *pregs)
53 {
54 struct of_device *op = of_find_device_by_node(isa_dev->prom_node);
56 if (!op || !op->num_irqs) {
57 isa_dev->irq = PCI_IRQ_NONE;
58 } else {
59 isa_dev->irq = op->irqs[0];
60 }
61 }
63 static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
64 {
65 struct device_node *dp = parent_isa_dev->prom_node->child;
67 if (!dp)
68 return;
70 printk(" ->");
71 while (dp) {
72 struct linux_prom_registers *regs;
73 struct sparc_isa_device *isa_dev;
75 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
76 if (!isa_dev) {
77 fatal_err("cannot allocate child isa_dev");
78 prom_halt();
79 }
81 memset(isa_dev, 0, sizeof(*isa_dev));
83 /* Link it in to parent. */
84 isa_dev->next = parent_isa_dev->child;
85 parent_isa_dev->child = isa_dev;
87 isa_dev->bus = parent_isa_dev->bus;
88 isa_dev->prom_node = dp;
90 regs = isa_dev_get_resource(isa_dev);
91 isa_dev_get_irq(isa_dev, regs);
93 report_dev(isa_dev, 1);
95 dp = dp->sibling;
96 }
97 }
99 static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
100 {
101 struct device_node *dp = isa_br->prom_node->child;
103 while (dp) {
104 struct linux_prom_registers *regs;
105 struct sparc_isa_device *isa_dev;
107 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
108 if (!isa_dev) {
109 printk(KERN_DEBUG "ISA: cannot allocate isa_dev");
110 return;
111 }
113 memset(isa_dev, 0, sizeof(*isa_dev));
115 isa_dev->ofdev.node = dp;
116 isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev;
117 isa_dev->ofdev.dev.bus = &isa_bus_type;
118 strcpy(isa_dev->ofdev.dev.bus_id, dp->path_component_name);
120 /* Register with core */
121 if (of_device_register(&isa_dev->ofdev) != 0) {
122 printk(KERN_DEBUG "isa: device registration error for %s!\n",
123 isa_dev->ofdev.dev.bus_id);
124 kfree(isa_dev);
125 goto next_sibling;
126 }
128 /* Link it in. */
129 isa_dev->next = NULL;
130 if (isa_br->devices == NULL) {
131 isa_br->devices = isa_dev;
132 } else {
133 struct sparc_isa_device *tmp = isa_br->devices;
135 while (tmp->next)
136 tmp = tmp->next;
138 tmp->next = isa_dev;
139 }
141 isa_dev->bus = isa_br;
142 isa_dev->prom_node = dp;
144 regs = isa_dev_get_resource(isa_dev);
145 isa_dev_get_irq(isa_dev, regs);
147 report_dev(isa_dev, 0);
149 isa_fill_children(isa_dev);
151 printk("]");
153 next_sibling:
154 dp = dp->sibling;
155 }
156 }
158 void __init isa_init(void)
159 {
160 struct pci_dev *pdev;
161 unsigned short vendor, device;
162 int index = 0;
164 vendor = PCI_VENDOR_ID_AL;
165 device = PCI_DEVICE_ID_AL_M1533;
167 pdev = NULL;
168 while ((pdev = pci_get_device(vendor, device, pdev)) != NULL) {
169 struct pcidev_cookie *pdev_cookie;
170 struct pci_pbm_info *pbm;
171 struct sparc_isa_bridge *isa_br;
172 struct device_node *dp;
174 pdev_cookie = pdev->sysdata;
175 if (!pdev_cookie) {
176 printk("ISA: Warning, ISA bridge ignored due to "
177 "lack of OBP data.\n");
178 continue;
179 }
180 pbm = pdev_cookie->pbm;
181 dp = pdev_cookie->prom_node;
183 isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL);
184 if (!isa_br) {
185 printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge");
186 return;
187 }
189 memset(isa_br, 0, sizeof(*isa_br));
191 isa_br->ofdev.node = dp;
192 isa_br->ofdev.dev.parent = &pdev->dev;
193 isa_br->ofdev.dev.bus = &isa_bus_type;
194 strcpy(isa_br->ofdev.dev.bus_id, dp->path_component_name);
196 /* Register with core */
197 if (of_device_register(&isa_br->ofdev) != 0) {
198 printk(KERN_DEBUG "isa: device registration error for %s!\n",
199 isa_br->ofdev.dev.bus_id);
200 kfree(isa_br);
201 return;
202 }
204 /* Link it in. */
205 isa_br->next = isa_chain;
206 isa_chain = isa_br;
208 isa_br->parent = pbm;
209 isa_br->self = pdev;
210 isa_br->index = index++;
211 isa_br->prom_node = pdev_cookie->prom_node;
213 printk("isa%d:", isa_br->index);
215 isa_fill_devices(isa_br);
217 printk("\n");
218 }
219 }