ia64/linux-2.6.18-xen.hg

view arch/mips/pci/ops-gt64120.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) 1999, 2000, 2004 MIPS Technologies, Inc.
3 * All rights reserved.
4 * Authors: Carsten Langgaard <carstenl@mips.com>
5 * Maciej W. Rozycki <macro@mips.com>
6 *
7 * This program is free software; you can distribute it and/or modify it
8 * under the terms of the GNU General Public License (Version 2) as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 */
20 #include <linux/types.h>
21 #include <linux/pci.h>
22 #include <linux/kernel.h>
24 #include <asm/gt64120.h>
26 #define PCI_ACCESS_READ 0
27 #define PCI_ACCESS_WRITE 1
29 /*
30 * PCI configuration cycle AD bus definition
31 */
32 /* Type 0 */
33 #define PCI_CFG_TYPE0_REG_SHF 0
34 #define PCI_CFG_TYPE0_FUNC_SHF 8
36 /* Type 1 */
37 #define PCI_CFG_TYPE1_REG_SHF 0
38 #define PCI_CFG_TYPE1_FUNC_SHF 8
39 #define PCI_CFG_TYPE1_DEV_SHF 11
40 #define PCI_CFG_TYPE1_BUS_SHF 16
42 static int gt64120_pcibios_config_access(unsigned char access_type,
43 struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
44 {
45 unsigned char busnum = bus->number;
46 u32 intr;
48 if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
49 return -1; /* Because of a bug in the galileo (for slot 31). */
51 /* Clear cause register bits */
52 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
53 GT_INTRCAUSE_TARABORT0_BIT));
55 /* Setup address */
56 GT_WRITE(GT_PCI0_CFGADDR_OFS,
57 (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) |
58 (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
59 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
60 GT_PCI0_CFGADDR_CONFIGEN_BIT);
62 if (access_type == PCI_ACCESS_WRITE) {
63 if (busnum == 0 && PCI_SLOT(devfn) == 0) {
64 /*
65 * The Galileo system controller is acting
66 * differently than other devices.
67 */
68 GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
69 } else
70 __GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
71 } else {
72 if (busnum == 0 && PCI_SLOT(devfn) == 0) {
73 /*
74 * The Galileo system controller is acting
75 * differently than other devices.
76 */
77 *data = GT_READ(GT_PCI0_CFGDATA_OFS);
78 } else
79 *data = __GT_READ(GT_PCI0_CFGDATA_OFS);
80 }
82 /* Check for master or target abort */
83 intr = GT_READ(GT_INTRCAUSE_OFS);
85 if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
86 /* Error occurred */
88 /* Clear bits */
89 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
90 GT_INTRCAUSE_TARABORT0_BIT));
92 return -1;
93 }
95 return 0;
96 }
99 /*
100 * We can't address 8 and 16 bit words directly. Instead we have to
101 * read/write a 32bit word and mask/modify the data we actually want.
102 */
103 static int gt64120_pcibios_read(struct pci_bus *bus, unsigned int devfn,
104 int where, int size, u32 * val)
105 {
106 u32 data = 0;
108 if (gt64120_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
109 &data))
110 return PCIBIOS_DEVICE_NOT_FOUND;
112 if (size == 1)
113 *val = (data >> ((where & 3) << 3)) & 0xff;
114 else if (size == 2)
115 *val = (data >> ((where & 3) << 3)) & 0xffff;
116 else
117 *val = data;
119 return PCIBIOS_SUCCESSFUL;
120 }
122 static int gt64120_pcibios_write(struct pci_bus *bus, unsigned int devfn,
123 int where, int size, u32 val)
124 {
125 u32 data = 0;
127 if (size == 4)
128 data = val;
129 else {
130 if (gt64120_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
131 where, &data))
132 return PCIBIOS_DEVICE_NOT_FOUND;
134 if (size == 1)
135 data = (data & ~(0xff << ((where & 3) << 3))) |
136 (val << ((where & 3) << 3));
137 else if (size == 2)
138 data = (data & ~(0xffff << ((where & 3) << 3))) |
139 (val << ((where & 3) << 3));
140 }
142 if (gt64120_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
143 &data))
144 return PCIBIOS_DEVICE_NOT_FOUND;
146 return PCIBIOS_SUCCESSFUL;
147 }
149 struct pci_ops gt64120_pci_ops = {
150 .read = gt64120_pcibios_read,
151 .write = gt64120_pcibios_write
152 };