ia64/linux-2.6.18-xen.hg

view arch/mips/pci/ops-pnx8550.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 *
3 * BRIEF MODULE DESCRIPTION
4 *
5 * 2.6 port, Embedded Alley Solutions, Inc
6 *
7 * Based on:
8 * Author: source@mvista.com
9 *
10 * This program is free software; you can distribute it and/or modify it
11 * under the terms of the GNU General Public License (Version 2) as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 */
23 #include <linux/types.h>
24 #include <linux/pci.h>
25 #include <linux/kernel.h>
26 #include <linux/init.h>
27 #include <linux/vmalloc.h>
28 #include <linux/delay.h>
30 #include <asm/mach-pnx8550/pci.h>
31 #include <asm/mach-pnx8550/glb.h>
32 #include <asm/debug.h>
35 static inline void clear_status(void)
36 {
37 unsigned long pci_stat;
39 pci_stat = inl(PCI_BASE | PCI_GPPM_STATUS);
40 outl(pci_stat, PCI_BASE | PCI_GPPM_ICLR);
41 }
43 static inline unsigned int
44 calc_cfg_addr(struct pci_bus *bus, unsigned int devfn, int where)
45 {
46 unsigned int addr;
48 addr = ((bus->number > 0) ? (((bus->number & 0xff) << PCI_CFG_BUS_SHIFT) | 1) : 0);
49 addr |= ((devfn & 0xff) << PCI_CFG_FUNC_SHIFT) | (where & 0xfc);
51 return addr;
52 }
54 static int
55 config_access(unsigned int pci_cmd, struct pci_bus *bus, unsigned int devfn, int where, unsigned int pci_mode, unsigned int *val)
56 {
57 unsigned int flags;
58 unsigned long loops = 0;
59 unsigned long ioaddr = calc_cfg_addr(bus, devfn, where);
61 local_irq_save(flags);
62 /*Clear pending interrupt status */
63 if (inl(PCI_BASE | PCI_GPPM_STATUS)) {
64 clear_status();
65 while (!(inl(PCI_BASE | PCI_GPPM_STATUS) == 0)) ;
66 }
68 outl(ioaddr, PCI_BASE | PCI_GPPM_ADDR);
70 if ((pci_cmd == PCI_CMD_IOW) || (pci_cmd == PCI_CMD_CONFIG_WRITE))
71 outl(*val, PCI_BASE | PCI_GPPM_WDAT);
73 outl(INIT_PCI_CYCLE | pci_cmd | (pci_mode & PCI_BYTE_ENABLE_MASK),
74 PCI_BASE | PCI_GPPM_CTRL);
76 loops =
77 ((loops_per_jiffy *
78 PCI_IO_JIFFIES_TIMEOUT) >> (PCI_IO_JIFFIES_SHIFT));
79 while (1) {
80 if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_DONE) {
81 if ((pci_cmd == PCI_CMD_IOR) ||
82 (pci_cmd == PCI_CMD_CONFIG_READ))
83 *val = inl(PCI_BASE | PCI_GPPM_RDAT);
84 clear_status();
85 local_irq_restore(flags);
86 return PCIBIOS_SUCCESSFUL;
87 } else if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_R_MABORT) {
88 break;
89 }
91 loops--;
92 if (loops == 0) {
93 printk("%s : Arbiter Locked.\n", __FUNCTION__);
94 }
95 }
97 clear_status();
98 if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) {
99 printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n",
100 __FUNCTION__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr,
101 pci_cmd);
102 }
104 if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_CONFIG_READ))
105 *val = 0xffffffff;
106 local_irq_restore(flags);
107 return PCIBIOS_DEVICE_NOT_FOUND;
108 }
110 /*
111 * We can't address 8 and 16 bit words directly. Instead we have to
112 * read/write a 32bit word and mask/modify the data we actually want.
113 */
114 static int
115 read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val)
116 {
117 unsigned int data = 0;
118 int err;
120 if (bus == 0)
121 return -1;
123 err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
124 switch (where & 0x03) {
125 case 0:
126 *val = (unsigned char)(data & 0x000000ff);
127 break;
128 case 1:
129 *val = (unsigned char)((data & 0x0000ff00) >> 8);
130 break;
131 case 2:
132 *val = (unsigned char)((data & 0x00ff0000) >> 16);
133 break;
134 case 3:
135 *val = (unsigned char)((data & 0xff000000) >> 24);
136 break;
137 }
139 return err;
140 }
142 static int
143 read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val)
144 {
145 unsigned int data = 0;
146 int err;
148 if (bus == 0)
149 return -1;
151 if (where & 0x01)
152 return PCIBIOS_BAD_REGISTER_NUMBER;
154 err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(3 << (where & 3)), &data);
155 switch (where & 0x02) {
156 case 0:
157 *val = (unsigned short)(data & 0x0000ffff);
158 break;
159 case 2:
160 *val = (unsigned short)((data & 0xffff0000) >> 16);
161 break;
162 }
164 return err;
165 }
167 static int
168 read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
169 {
170 int err;
171 if (bus == 0)
172 return -1;
174 if (where & 0x03)
175 return PCIBIOS_BAD_REGISTER_NUMBER;
177 err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, 0, val);
179 return err;
180 }
182 static int
183 write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
184 {
185 unsigned int data = (unsigned int)val;
186 int err;
188 if (bus == 0)
189 return -1;
191 switch (where & 0x03) {
192 case 1:
193 data = (data << 8);
194 break;
195 case 2:
196 data = (data << 16);
197 break;
198 case 3:
199 data = (data << 24);
200 break;
201 default:
202 break;
203 }
205 err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
207 return err;
208 }
210 static int
211 write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
212 {
213 unsigned int data = (unsigned int)val;
214 int err;
216 if (bus == 0)
217 return -1;
219 if (where & 0x01)
220 return PCIBIOS_BAD_REGISTER_NUMBER;
222 switch (where & 0x02) {
223 case 2:
224 data = (data << 16);
225 break;
226 default:
227 break;
228 }
229 err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(3 << (where & 3)), &data);
231 return err;
232 }
234 static int
235 write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
236 {
237 int err;
238 if (bus == 0)
239 return -1;
241 if (where & 0x03)
242 return PCIBIOS_BAD_REGISTER_NUMBER;
244 err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, 0, &val);
246 return err;
247 }
249 static int config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
250 {
251 switch (size) {
252 case 1: {
253 u8 _val;
254 int rc = read_config_byte(bus, devfn, where, &_val);
255 *val = _val;
256 return rc;
257 }
258 case 2: {
259 u16 _val;
260 int rc = read_config_word(bus, devfn, where, &_val);
261 *val = _val;
262 return rc;
263 }
264 default:
265 return read_config_dword(bus, devfn, where, val);
266 }
267 }
269 static int config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
270 {
271 switch (size) {
272 case 1:
273 return write_config_byte(bus, devfn, where, (u8) val);
274 case 2:
275 return write_config_word(bus, devfn, where, (u16) val);
276 default:
277 return write_config_dword(bus, devfn, where, val);
278 }
279 }
281 struct pci_ops pnx8550_pci_ops = {
282 config_read,
283 config_write
284 };