ia64/linux-2.6.18-xen.hg

view arch/mips/pci/pci-vr41xx.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 * pci-vr41xx.c, PCI Control Unit routines for the NEC VR4100 series.
3 *
4 * Copyright (C) 2001-2003 MontaVista Software Inc.
5 * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
6 * Copyright (C) 2004-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23 /*
24 * Changes:
25 * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
26 * - New creation, NEC VR4122 and VR4131 are supported.
27 */
28 #include <linux/init.h>
29 #include <linux/pci.h>
30 #include <linux/types.h>
32 #include <asm/cpu.h>
33 #include <asm/io.h>
34 #include <asm/vr41xx/pci.h>
35 #include <asm/vr41xx/vr41xx.h>
37 #include "pci-vr41xx.h"
39 extern struct pci_ops vr41xx_pci_ops;
41 static void __iomem *pciu_base;
43 #define pciu_read(offset) readl(pciu_base + (offset))
44 #define pciu_write(offset, value) writel((value), pciu_base + (offset))
46 static struct pci_master_address_conversion pci_master_memory1 = {
47 .bus_base_address = PCI_MASTER_MEM1_BUS_BASE_ADDRESS,
48 .address_mask = PCI_MASTER_MEM1_ADDRESS_MASK,
49 .pci_base_address = PCI_MASTER_MEM1_PCI_BASE_ADDRESS,
50 };
52 static struct pci_target_address_conversion pci_target_memory1 = {
53 .address_mask = PCI_TARGET_MEM1_ADDRESS_MASK,
54 .bus_base_address = PCI_TARGET_MEM1_BUS_BASE_ADDRESS,
55 };
57 static struct pci_master_address_conversion pci_master_io = {
58 .bus_base_address = PCI_MASTER_IO_BUS_BASE_ADDRESS,
59 .address_mask = PCI_MASTER_IO_ADDRESS_MASK,
60 .pci_base_address = PCI_MASTER_IO_PCI_BASE_ADDRESS,
61 };
63 static struct pci_mailbox_address pci_mailbox = {
64 .base_address = PCI_MAILBOX_BASE_ADDRESS,
65 };
67 static struct pci_target_address_window pci_target_window1 = {
68 .base_address = PCI_TARGET_WINDOW1_BASE_ADDRESS,
69 };
71 static struct resource pci_mem_resource = {
72 .name = "PCI Memory resources",
73 .start = PCI_MEM_RESOURCE_START,
74 .end = PCI_MEM_RESOURCE_END,
75 .flags = IORESOURCE_MEM,
76 };
78 static struct resource pci_io_resource = {
79 .name = "PCI I/O resources",
80 .start = PCI_IO_RESOURCE_START,
81 .end = PCI_IO_RESOURCE_END,
82 .flags = IORESOURCE_IO,
83 };
85 static struct pci_controller_unit_setup vr41xx_pci_controller_unit_setup = {
86 .master_memory1 = &pci_master_memory1,
87 .target_memory1 = &pci_target_memory1,
88 .master_io = &pci_master_io,
89 .exclusive_access = CANNOT_LOCK_FROM_DEVICE,
90 .wait_time_limit_from_irdy_to_trdy = 0,
91 .mailbox = &pci_mailbox,
92 .target_window1 = &pci_target_window1,
93 .master_latency_timer = 0x80,
94 .retry_limit = 0,
95 .arbiter_priority_control = PCI_ARBITRATION_MODE_FAIR,
96 .take_away_gnt_mode = PCI_TAKE_AWAY_GNT_DISABLE,
97 };
99 static struct pci_controller vr41xx_pci_controller = {
100 .pci_ops = &vr41xx_pci_ops,
101 .mem_resource = &pci_mem_resource,
102 .io_resource = &pci_io_resource,
103 };
105 void __init vr41xx_pciu_setup(struct pci_controller_unit_setup *setup)
106 {
107 vr41xx_pci_controller_unit_setup = *setup;
108 }
110 static int __init vr41xx_pciu_init(void)
111 {
112 struct pci_controller_unit_setup *setup;
113 struct pci_master_address_conversion *master;
114 struct pci_target_address_conversion *target;
115 struct pci_mailbox_address *mailbox;
116 struct pci_target_address_window *window;
117 unsigned long vtclock, pci_clock_max;
118 uint32_t val;
120 setup = &vr41xx_pci_controller_unit_setup;
122 if (request_mem_region(PCIU_BASE, PCIU_SIZE, "PCIU") == NULL)
123 return -EBUSY;
125 pciu_base = ioremap(PCIU_BASE, PCIU_SIZE);
126 if (pciu_base == NULL) {
127 release_mem_region(PCIU_BASE, PCIU_SIZE);
128 return -EBUSY;
129 }
131 /* Disable PCI interrupt */
132 vr41xx_disable_pciint();
134 /* Supply VTClock to PCIU */
135 vr41xx_supply_clock(PCIU_CLOCK);
137 /* Dummy write, waiting for supply of VTClock. */
138 vr41xx_disable_pciint();
140 /* Select PCI clock */
141 if (setup->pci_clock_max != 0)
142 pci_clock_max = setup->pci_clock_max;
143 else
144 pci_clock_max = PCI_CLOCK_MAX;
145 vtclock = vr41xx_get_vtclock_frequency();
146 if (vtclock < pci_clock_max)
147 pciu_write(PCICLKSELREG, EQUAL_VTCLOCK);
148 else if ((vtclock / 2) < pci_clock_max)
149 pciu_write(PCICLKSELREG, HALF_VTCLOCK);
150 else if (current_cpu_data.processor_id >= PRID_VR4131_REV2_1 &&
151 (vtclock / 3) < pci_clock_max)
152 pciu_write(PCICLKSELREG, ONE_THIRD_VTCLOCK);
153 else if ((vtclock / 4) < pci_clock_max)
154 pciu_write(PCICLKSELREG, QUARTER_VTCLOCK);
155 else {
156 printk(KERN_ERR "PCI Clock is over 33MHz.\n");
157 return -EINVAL;
158 }
160 /* Supply PCI clock by PCI bus */
161 vr41xx_supply_clock(PCI_CLOCK);
163 if (setup->master_memory1 != NULL) {
164 master = setup->master_memory1;
165 val = IBA(master->bus_base_address) |
166 MASTER_MSK(master->address_mask) |
167 WINEN |
168 PCIA(master->pci_base_address);
169 pciu_write(PCIMMAW1REG, val);
170 } else {
171 val = pciu_read(PCIMMAW1REG);
172 val &= ~WINEN;
173 pciu_write(PCIMMAW1REG, val);
174 }
176 if (setup->master_memory2 != NULL) {
177 master = setup->master_memory2;
178 val = IBA(master->bus_base_address) |
179 MASTER_MSK(master->address_mask) |
180 WINEN |
181 PCIA(master->pci_base_address);
182 pciu_write(PCIMMAW2REG, val);
183 } else {
184 val = pciu_read(PCIMMAW2REG);
185 val &= ~WINEN;
186 pciu_write(PCIMMAW2REG, val);
187 }
189 if (setup->target_memory1 != NULL) {
190 target = setup->target_memory1;
191 val = TARGET_MSK(target->address_mask) |
192 WINEN |
193 ITA(target->bus_base_address);
194 pciu_write(PCITAW1REG, val);
195 } else {
196 val = pciu_read(PCITAW1REG);
197 val &= ~WINEN;
198 pciu_write(PCITAW1REG, val);
199 }
201 if (setup->target_memory2 != NULL) {
202 target = setup->target_memory2;
203 val = TARGET_MSK(target->address_mask) |
204 WINEN |
205 ITA(target->bus_base_address);
206 pciu_write(PCITAW2REG, val);
207 } else {
208 val = pciu_read(PCITAW2REG);
209 val &= ~WINEN;
210 pciu_write(PCITAW2REG, val);
211 }
213 if (setup->master_io != NULL) {
214 master = setup->master_io;
215 val = IBA(master->bus_base_address) |
216 MASTER_MSK(master->address_mask) |
217 WINEN |
218 PCIIA(master->pci_base_address);
219 pciu_write(PCIMIOAWREG, val);
220 } else {
221 val = pciu_read(PCIMIOAWREG);
222 val &= ~WINEN;
223 pciu_write(PCIMIOAWREG, val);
224 }
226 if (setup->exclusive_access == CANNOT_LOCK_FROM_DEVICE)
227 pciu_write(PCIEXACCREG, UNLOCK);
228 else
229 pciu_write(PCIEXACCREG, 0);
231 if (current_cpu_data.cputype == CPU_VR4122)
232 pciu_write(PCITRDYVREG, TRDYV(setup->wait_time_limit_from_irdy_to_trdy));
234 pciu_write(LATTIMEREG, MLTIM(setup->master_latency_timer));
236 if (setup->mailbox != NULL) {
237 mailbox = setup->mailbox;
238 val = MBADD(mailbox->base_address) | TYPE_32BITSPACE |
239 MSI_MEMORY | PREF_APPROVAL;
240 pciu_write(MAILBAREG, val);
241 }
243 if (setup->target_window1) {
244 window = setup->target_window1;
245 val = PMBA(window->base_address) | TYPE_32BITSPACE |
246 MSI_MEMORY | PREF_APPROVAL;
247 pciu_write(PCIMBA1REG, val);
248 }
250 if (setup->target_window2) {
251 window = setup->target_window2;
252 val = PMBA(window->base_address) | TYPE_32BITSPACE |
253 MSI_MEMORY | PREF_APPROVAL;
254 pciu_write(PCIMBA2REG, val);
255 }
257 val = pciu_read(RETVALREG);
258 val &= ~RTYVAL_MASK;
259 val |= RTYVAL(setup->retry_limit);
260 pciu_write(RETVALREG, val);
262 val = pciu_read(PCIAPCNTREG);
263 val &= ~(TKYGNT | PAPC);
265 switch (setup->arbiter_priority_control) {
266 case PCI_ARBITRATION_MODE_ALTERNATE_0:
267 val |= PAPC_ALTERNATE_0;
268 break;
269 case PCI_ARBITRATION_MODE_ALTERNATE_B:
270 val |= PAPC_ALTERNATE_B;
271 break;
272 default:
273 val |= PAPC_FAIR;
274 break;
275 }
277 if (setup->take_away_gnt_mode == PCI_TAKE_AWAY_GNT_ENABLE)
278 val |= TKYGNT_ENABLE;
280 pciu_write(PCIAPCNTREG, val);
282 pciu_write(COMMANDREG, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
283 PCI_COMMAND_MASTER | PCI_COMMAND_PARITY |
284 PCI_COMMAND_SERR);
286 /* Clear bus error */
287 pciu_read(BUSERRADREG);
289 pciu_write(PCIENREG, PCIU_CONFIG_DONE);
291 if (setup->mem_resource != NULL)
292 vr41xx_pci_controller.mem_resource = setup->mem_resource;
294 if (setup->io_resource != NULL) {
295 vr41xx_pci_controller.io_resource = setup->io_resource;
296 } else {
297 set_io_port_base(IO_PORT_BASE);
298 ioport_resource.start = IO_PORT_RESOURCE_START;
299 ioport_resource.end = IO_PORT_RESOURCE_END;
300 }
302 register_pci_controller(&vr41xx_pci_controller);
304 return 0;
305 }
307 arch_initcall(vr41xx_pciu_init);