ia64/linux-2.6.18-xen.hg

view arch/mips/pci/ops-tx4927.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 2001 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ahennessy@mvista.com
5 *
6 * Copyright (C) 2000-2001 Toshiba Corporation
7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
8 *
9 * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
10 *
11 * Define the pci_ops for the Toshiba rbtx4927
12 *
13 * Much of the code is derived from the original DDB5074 port by
14 * Geert Uytterhoeven <geert@sonycom.com>
15 *
16 * Copyright 2004 MontaVista Software Inc.
17 * Author: Manish Lachwani (mlachwani@mvista.com)
18 *
19 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the
21 * Free Software Foundation; either version 2 of the License, or (at your
22 * option) any later version.
23 *
24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
27 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 * You should have received a copy of the GNU General Public License along
36 * with this program; if not, write to the Free Software Foundation, Inc.,
37 * 675 Mass Ave, Cambridge, MA 02139, USA.
38 */
39 #include <linux/types.h>
40 #include <linux/pci.h>
41 #include <linux/kernel.h>
42 #include <linux/init.h>
44 #include <asm/addrspace.h>
45 #include <asm/byteorder.h>
46 #include <asm/tx4927/tx4927_pci.h>
48 /* initialize in setup */
49 struct resource pci_io_resource = {
50 .name = "TX4927 PCI IO SPACE",
51 .start = 0x1000,
52 .end = (0x1000 + (TX4927_PCIIO_SIZE)) - 1,
53 .flags = IORESOURCE_IO
54 };
56 /* initialize in setup */
57 struct resource pci_mem_resource = {
58 .name = "TX4927 PCI MEM SPACE",
59 .start = TX4927_PCIMEM,
60 .end = TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1,
61 .flags = IORESOURCE_MEM
62 };
64 static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
65 {
66 if (bus > 0) {
67 /* Type 1 configuration */
68 tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
69 ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
70 } else {
71 if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0))
72 return -1;
74 /* Type 0 configuration */
75 tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
76 ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
77 }
78 /* clear M_ABORT and Disable M_ABORT Int. */
79 tx4927_pcicptr->pcistatus =
80 (tx4927_pcicptr->pcistatus & 0x0000ffff) |
81 (PCI_STATUS_REC_MASTER_ABORT << 16);
82 tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
83 return 0;
84 }
86 static int check_abort(int flags)
87 {
88 int code = PCIBIOS_SUCCESSFUL;
89 if (tx4927_pcicptr->
90 pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
91 tx4927_pcicptr->pcistatus =
92 (tx4927_pcicptr->
93 pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
94 << 16);
95 tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
96 code = PCIBIOS_DEVICE_NOT_FOUND;
97 }
98 return code;
99 }
101 static int tx4927_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, int where,
102 int size, u32 * val)
103 {
104 int flags, retval, dev, busno, func;
106 busno = bus->number;
107 dev = PCI_SLOT(devfn);
108 func = PCI_FUNC(devfn);
110 /* check if the bus is top-level */
111 if (bus->parent != NULL) {
112 busno = bus->number;
113 } else {
114 busno = 0;
115 }
117 if (mkaddr(busno, devfn, where, &flags))
118 return -1;
120 switch (size) {
121 case 1:
122 *val = *(volatile u8 *) ((unsigned long) & tx4927_pcicptr->
123 g2pcfgdata |
124 #ifdef __LITTLE_ENDIAN
125 (where & 3));
126 #else
127 ((where & 0x3) ^ 0x3));
128 #endif
129 break;
130 case 2:
131 *val = *(volatile u16 *) ((unsigned long) & tx4927_pcicptr->
132 g2pcfgdata |
133 #ifdef __LITTLE_ENDIAN
134 (where & 3));
135 #else
136 ((where & 0x3) ^ 0x2));
137 #endif
138 break;
139 case 4:
140 *val = tx4927_pcicptr->g2pcfgdata;
141 break;
142 }
144 retval = check_abort(flags);
145 if (retval == PCIBIOS_DEVICE_NOT_FOUND)
146 *val = 0xffffffff;
148 return retval;
149 }
151 static int tx4927_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
152 int size, u32 val)
153 {
154 int flags, dev, busno, func;
155 busno = bus->number;
156 dev = PCI_SLOT(devfn);
157 func = PCI_FUNC(devfn);
159 /* check if the bus is top-level */
160 if (bus->parent != NULL) {
161 busno = bus->number;
162 } else {
163 busno = 0;
164 }
166 if (mkaddr(busno, devfn, where, &flags))
167 return -1;
169 switch (size) {
170 case 1:
171 *(volatile u8 *) ((unsigned long) & tx4927_pcicptr->
172 g2pcfgdata |
173 #ifdef __LITTLE_ENDIAN
174 (where & 3)) = val;
175 #else
176 ((where & 0x3) ^ 0x3)) = val;
177 #endif
178 break;
180 case 2:
181 *(volatile u16 *) ((unsigned long) & tx4927_pcicptr->
182 g2pcfgdata |
183 #ifdef __LITTLE_ENDIAN
184 (where & 3)) = val;
185 #else
186 ((where & 0x3) ^ 0x2)) = val;
187 #endif
188 break;
189 case 4:
190 tx4927_pcicptr->g2pcfgdata = val;
191 break;
192 }
194 return check_abort(flags);
195 }
197 struct pci_ops tx4927_pci_ops = {
198 tx4927_pcibios_read_config,
199 tx4927_pcibios_write_config
200 };
202 /*
203 * h/w only supports devices 0x00 to 0x14
204 */
205 struct pci_controller tx4927_controller = {
206 .pci_ops = &tx4927_pci_ops,
207 .io_resource = &pci_io_resource,
208 .mem_resource = &pci_mem_resource,
209 };