ia64/linux-2.6.18-xen.hg

view arch/mips/pci/pci-ip32.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 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2000, 2001 Keith M Wesolowski
7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
8 */
9 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/interrupt.h>
12 #include <linux/pci.h>
13 #include <linux/types.h>
14 #include <asm/ip32/mace.h>
15 #include <asm/ip32/ip32_ints.h>
17 #undef DEBUG_MACE_PCI
19 /*
20 * Handle errors from the bridge. This includes master and target aborts,
21 * various command and address errors, and the interrupt test. This gets
22 * registered on the bridge error irq. It's conceivable that some of these
23 * conditions warrant a panic. Anybody care to say which ones?
24 */
25 static irqreturn_t macepci_error(int irq, void *dev, struct pt_regs *regs)
26 {
27 char s;
28 unsigned int flags = mace->pci.error;
29 unsigned int addr = mace->pci.error_addr;
31 if (flags & MACEPCI_ERROR_MEMORY_ADDR)
32 s = 'M';
33 else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
34 s = 'C';
35 else
36 s = 'X';
38 if (flags & MACEPCI_ERROR_MASTER_ABORT) {
39 printk("MACEPCI: Master abort at 0x%08x (%c)\n", addr, s);
40 flags &= ~MACEPCI_ERROR_MASTER_ABORT;
41 }
42 if (flags & MACEPCI_ERROR_TARGET_ABORT) {
43 printk("MACEPCI: Target abort at 0x%08x (%c)\n", addr, s);
44 flags &= ~MACEPCI_ERROR_TARGET_ABORT;
45 }
46 if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
47 printk("MACEPCI: Data parity error at 0x%08x (%c)\n", addr, s);
48 flags &= ~MACEPCI_ERROR_DATA_PARITY_ERR;
49 }
50 if (flags & MACEPCI_ERROR_RETRY_ERR) {
51 printk("MACEPCI: Retry error at 0x%08x (%c)\n", addr, s);
52 flags &= ~MACEPCI_ERROR_RETRY_ERR;
53 }
54 if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
55 printk("MACEPCI: Illegal command at 0x%08x (%c)\n", addr, s);
56 flags &= ~MACEPCI_ERROR_ILLEGAL_CMD;
57 }
58 if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
59 printk("MACEPCI: System error at 0x%08x (%c)\n", addr, s);
60 flags &= ~MACEPCI_ERROR_SYSTEM_ERR;
61 }
62 if (flags & MACEPCI_ERROR_PARITY_ERR) {
63 printk("MACEPCI: Parity error at 0x%08x (%c)\n", addr, s);
64 flags &= ~MACEPCI_ERROR_PARITY_ERR;
65 }
66 if (flags & MACEPCI_ERROR_OVERRUN) {
67 printk("MACEPCI: Overrun error at 0x%08x (%c)\n", addr, s);
68 flags &= ~MACEPCI_ERROR_OVERRUN;
69 }
70 if (flags & MACEPCI_ERROR_SIG_TABORT) {
71 printk("MACEPCI: Signaled target abort (clearing)\n");
72 flags &= ~MACEPCI_ERROR_SIG_TABORT;
73 }
74 if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
75 printk("MACEPCI: Interrupt test triggered (clearing)\n");
76 flags &= ~MACEPCI_ERROR_INTERRUPT_TEST;
77 }
79 mace->pci.error = flags;
81 return IRQ_HANDLED;
82 }
85 extern struct pci_ops mace_pci_ops;
86 #ifdef CONFIG_64BIT
87 static struct resource mace_pci_mem_resource = {
88 .name = "SGI O2 PCI MEM",
89 .start = MACEPCI_HI_MEMORY,
90 .end = 0x2FFFFFFFFUL,
91 .flags = IORESOURCE_MEM,
92 };
93 static struct resource mace_pci_io_resource = {
94 .name = "SGI O2 PCI IO",
95 .start = 0x00000000UL,
96 .end = 0xffffffffUL,
97 .flags = IORESOURCE_IO,
98 };
99 #define MACE_PCI_MEM_OFFSET 0x200000000
100 #else
101 static struct resource mace_pci_mem_resource = {
102 .name = "SGI O2 PCI MEM",
103 .start = MACEPCI_LOW_MEMORY,
104 .end = MACEPCI_LOW_MEMORY + 0x2000000 - 1,
105 .flags = IORESOURCE_MEM,
106 };
107 static struct resource mace_pci_io_resource = {
108 .name = "SGI O2 PCI IO",
109 .start = 0x00000000,
110 .end = 0xFFFFFFFF,
111 .flags = IORESOURCE_IO,
112 };
113 #define MACE_PCI_MEM_OFFSET (MACEPCI_LOW_MEMORY - 0x80000000)
114 #endif
115 static struct pci_controller mace_pci_controller = {
116 .pci_ops = &mace_pci_ops,
117 .mem_resource = &mace_pci_mem_resource,
118 .io_resource = &mace_pci_io_resource,
119 .iommu = 0,
120 .mem_offset = MACE_PCI_MEM_OFFSET,
121 .io_offset = 0,
122 };
124 static int __init mace_init(void)
125 {
126 PCIBIOS_MIN_IO = 0x1000;
128 /* Clear any outstanding errors and enable interrupts */
129 mace->pci.error_addr = 0;
130 mace->pci.error = 0;
131 mace->pci.control = 0xff008500;
133 printk("MACE PCI rev %d\n", mace->pci.rev);
135 BUG_ON(request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
136 "MACE PCI error", NULL));
138 iomem_resource = mace_pci_mem_resource;
139 ioport_resource = mace_pci_io_resource;
141 register_pci_controller(&mace_pci_controller);
143 return 0;
144 }
146 arch_initcall(mace_init);