ia64/linux-2.6.18-xen.hg

view arch/mips/pci/pci-bcm1480ht.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) 2001,2002,2005 Broadcom Corporation
3 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (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 /*
21 * BCM1480/1455-specific HT support (looking like PCI)
22 *
23 * This module provides the glue between Linux's PCI subsystem
24 * and the hardware. We basically provide glue for accessing
25 * configuration space, and set up the translation for I/O
26 * space accesses.
27 *
28 * To access configuration space, we use ioremap. In the 32-bit
29 * kernel, this consumes either 4 or 8 page table pages, and 16MB of
30 * kernel mapped memory. Hopefully neither of these should be a huge
31 * problem.
32 *
33 */
34 #include <linux/types.h>
35 #include <linux/pci.h>
36 #include <linux/kernel.h>
37 #include <linux/init.h>
38 #include <linux/mm.h>
39 #include <linux/console.h>
40 #include <linux/tty.h>
42 #include <asm/sibyte/bcm1480_regs.h>
43 #include <asm/sibyte/bcm1480_scd.h>
44 #include <asm/sibyte/board.h>
45 #include <asm/io.h>
47 /*
48 * Macros for calculating offsets into config space given a device
49 * structure or dev/fun/reg
50 */
51 #define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where))
52 #define CFGADDR(bus,devfn,where) CFGOFFSET((bus)->number,(devfn),where)
54 static void *ht_cfg_space;
56 #define PCI_BUS_ENABLED 1
57 #define PCI_DEVICE_MODE 2
59 static int bcm1480ht_bus_status = 0;
61 #define PCI_BRIDGE_DEVICE 0
62 #define HT_BRIDGE_DEVICE 1
64 /*
65 * HT's level-sensitive interrupts require EOI, which is generated
66 * through a 4MB memory-mapped region
67 */
68 unsigned long ht_eoi_space;
70 /*
71 * Read/write 32-bit values in config space.
72 */
73 static inline u32 READCFG32(u32 addr)
74 {
75 return *(u32 *)(ht_cfg_space + (addr&~3));
76 }
78 static inline void WRITECFG32(u32 addr, u32 data)
79 {
80 *(u32 *)(ht_cfg_space + (addr & ~3)) = data;
81 }
83 /*
84 * Some checks before doing config cycles:
85 * In PCI Device Mode, hide everything on bus 0 except the LDT host
86 * bridge. Otherwise, access is controlled by bridge MasterEn bits.
87 */
88 static int bcm1480ht_can_access(struct pci_bus *bus, int devfn)
89 {
90 u32 devno;
92 if (!(bcm1480ht_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
93 return 0;
95 if (bus->number == 0) {
96 devno = PCI_SLOT(devfn);
97 if (bcm1480ht_bus_status & PCI_DEVICE_MODE)
98 return 0;
99 }
100 return 1;
101 }
103 /*
104 * Read/write access functions for various sizes of values
105 * in config space. Return all 1's for disallowed accesses
106 * for a kludgy but adequate simulation of master aborts.
107 */
109 static int bcm1480ht_pcibios_read(struct pci_bus *bus, unsigned int devfn,
110 int where, int size, u32 * val)
111 {
112 u32 data = 0;
114 if ((size == 2) && (where & 1))
115 return PCIBIOS_BAD_REGISTER_NUMBER;
116 else if ((size == 4) && (where & 3))
117 return PCIBIOS_BAD_REGISTER_NUMBER;
119 if (bcm1480ht_can_access(bus, devfn))
120 data = READCFG32(CFGADDR(bus, devfn, where));
121 else
122 data = 0xFFFFFFFF;
124 if (size == 1)
125 *val = (data >> ((where & 3) << 3)) & 0xff;
126 else if (size == 2)
127 *val = (data >> ((where & 3) << 3)) & 0xffff;
128 else
129 *val = data;
131 return PCIBIOS_SUCCESSFUL;
132 }
134 static int bcm1480ht_pcibios_write(struct pci_bus *bus, unsigned int devfn,
135 int where, int size, u32 val)
136 {
137 u32 cfgaddr = CFGADDR(bus, devfn, where);
138 u32 data = 0;
140 if ((size == 2) && (where & 1))
141 return PCIBIOS_BAD_REGISTER_NUMBER;
142 else if ((size == 4) && (where & 3))
143 return PCIBIOS_BAD_REGISTER_NUMBER;
145 if (!bcm1480ht_can_access(bus, devfn))
146 return PCIBIOS_BAD_REGISTER_NUMBER;
148 data = READCFG32(cfgaddr);
150 if (size == 1)
151 data = (data & ~(0xff << ((where & 3) << 3))) |
152 (val << ((where & 3) << 3));
153 else if (size == 2)
154 data = (data & ~(0xffff << ((where & 3) << 3))) |
155 (val << ((where & 3) << 3));
156 else
157 data = val;
159 WRITECFG32(cfgaddr, data);
161 return PCIBIOS_SUCCESSFUL;
162 }
164 static int bcm1480ht_pcibios_get_busno(void)
165 {
166 return 0;
167 }
169 struct pci_ops bcm1480ht_pci_ops = {
170 .read = bcm1480ht_pcibios_read,
171 .write = bcm1480ht_pcibios_write,
172 };
174 static struct resource bcm1480ht_mem_resource = {
175 .name = "BCM1480 HT MEM",
176 .start = 0x40000000UL,
177 .end = 0x5fffffffUL,
178 .flags = IORESOURCE_MEM,
179 };
181 static struct resource bcm1480ht_io_resource = {
182 .name = "BCM1480 HT I/O",
183 .start = 0x00000000UL,
184 .end = 0x01ffffffUL,
185 .flags = IORESOURCE_IO,
186 };
188 struct pci_controller bcm1480ht_controller = {
189 .pci_ops = &bcm1480ht_pci_ops,
190 .mem_resource = &bcm1480ht_mem_resource,
191 .io_resource = &bcm1480ht_io_resource,
192 .index = 1,
193 .get_busno = bcm1480ht_pcibios_get_busno,
194 };
196 static int __init bcm1480ht_pcibios_init(void)
197 {
198 uint32_t cmdreg;
200 ht_cfg_space = ioremap(A_BCM1480_PHYS_HT_CFG_MATCH_BITS, 16*1024*1024);
202 /*
203 * See if the PCI bus has been configured by the firmware.
204 */
205 cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
206 PCI_COMMAND));
207 if (!(cmdreg & PCI_COMMAND_MASTER)) {
208 printk("HT: Skipping HT probe. Bus is not initialized.\n");
209 iounmap(ht_cfg_space);
210 return 1; /* XXX */
211 }
212 bcm1480ht_bus_status |= PCI_BUS_ENABLED;
214 ht_eoi_space = (unsigned long)
215 ioremap(A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES,
216 4 * 1024 * 1024);
218 register_pci_controller(&bcm1480ht_controller);
220 return 0;
221 }
223 arch_initcall(bcm1480ht_pcibios_init);