ia64/linux-2.6.18-xen.hg

view arch/alpha/kernel/core_polaris.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 * linux/arch/alpha/kernel/core_polaris.c
3 *
4 * POLARIS chip-specific code
5 */
7 #define __EXTERN_INLINE inline
8 #include <asm/io.h>
9 #include <asm/core_polaris.h>
10 #undef __EXTERN_INLINE
12 #include <linux/types.h>
13 #include <linux/pci.h>
14 #include <linux/sched.h>
15 #include <linux/init.h>
17 #include <asm/ptrace.h>
19 #include "proto.h"
20 #include "pci_impl.h"
22 /*
23 * BIOS32-style PCI interface:
24 */
26 #define DEBUG_CONFIG 0
28 #if DEBUG_CONFIG
29 # define DBG_CFG(args) printk args
30 #else
31 # define DBG_CFG(args)
32 #endif
35 /*
36 * Given a bus, device, and function number, compute resulting
37 * configuration space address. This is fairly straightforward
38 * on POLARIS, since the chip itself generates Type 0 or Type 1
39 * cycles automatically depending on the bus number (Bus 0 is
40 * hardwired to Type 0, all others are Type 1. Peer bridges
41 * are not supported).
42 *
43 * All types:
44 *
45 * 3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
46 * 9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 * |1|1|1|1|1|0|0|1|1|1|1|1|1|1|1|0|B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|x|x|
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 *
51 * 23:16 bus number (8 bits = 128 possible buses)
52 * 15:11 Device number (5 bits)
53 * 10:8 function number
54 * 7:2 register number
55 *
56 * Notes:
57 * The function number selects which function of a multi-function device
58 * (e.g., scsi and ethernet).
59 *
60 * The register selects a DWORD (32 bit) register offset. Hence it
61 * doesn't get shifted by 2 bits as we want to "drop" the bottom two
62 * bits.
63 */
65 static int
66 mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
67 unsigned long *pci_addr, u8 *type1)
68 {
69 u8 bus = pbus->number;
71 *type1 = (bus == 0) ? 0 : 1;
72 *pci_addr = (bus << 16) | (device_fn << 8) | (where) |
73 POLARIS_DENSE_CONFIG_BASE;
75 DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
76 " returning address 0x%p\n"
77 bus, device_fn, where, *pci_addr));
79 return 0;
80 }
82 static int
83 polaris_read_config(struct pci_bus *bus, unsigned int devfn, int where,
84 int size, u32 *value)
85 {
86 unsigned long addr;
87 unsigned char type1;
89 if (mk_conf_addr(bus, devfn, where, &addr, &type1))
90 return PCIBIOS_DEVICE_NOT_FOUND;
92 switch (size) {
93 case 1:
94 *value = __kernel_ldbu(*(vucp)addr);
95 break;
96 case 2:
97 *value = __kernel_ldwu(*(vusp)addr);
98 break;
99 case 4:
100 *value = *(vuip)addr;
101 break;
102 }
104 return PCIBIOS_SUCCESSFUL;
105 }
108 static int
109 polaris_write_config(struct pci_bus *bus, unsigned int devfn, int where,
110 int size, u32 value)
111 {
112 unsigned long addr;
113 unsigned char type1;
115 if (mk_conf_addr(bus, devfn, where, &addr, &type1))
116 return PCIBIOS_DEVICE_NOT_FOUND;
118 switch (size) {
119 case 1:
120 __kernel_stb(value, *(vucp)addr);
121 mb();
122 __kernel_ldbu(*(vucp)addr);
123 break;
124 case 2:
125 __kernel_stw(value, *(vusp)addr);
126 mb();
127 __kernel_ldwu(*(vusp)addr);
128 break;
129 case 4:
130 *(vuip)addr = value;
131 mb();
132 *(vuip)addr;
133 break;
134 }
136 return PCIBIOS_SUCCESSFUL;
137 }
139 struct pci_ops polaris_pci_ops =
140 {
141 .read = polaris_read_config,
142 .write = polaris_write_config,
143 };
145 void __init
146 polaris_init_arch(void)
147 {
148 struct pci_controller *hose;
150 /* May need to initialize error reporting (see PCICTL0/1), but
151 * for now assume that the firmware has done the right thing
152 * already.
153 */
154 #if 0
155 printk("polaris_init_arch(): trusting firmware for setup\n");
156 #endif
158 /*
159 * Create our single hose.
160 */
162 pci_isa_hose = hose = alloc_pci_controller();
163 hose->io_space = &ioport_resource;
164 hose->mem_space = &iomem_resource;
165 hose->index = 0;
167 hose->sparse_mem_base = 0;
168 hose->dense_mem_base = POLARIS_DENSE_MEM_BASE - IDENT_ADDR;
169 hose->sparse_io_base = 0;
170 hose->dense_io_base = POLARIS_DENSE_IO_BASE - IDENT_ADDR;
172 hose->sg_isa = hose->sg_pci = NULL;
174 /* The I/O window is fixed at 2G @ 2G. */
175 __direct_map_base = 0x80000000;
176 __direct_map_size = 0x80000000;
177 }
179 static inline void
180 polaris_pci_clr_err(void)
181 {
182 *(vusp)POLARIS_W_STATUS;
183 /* Write 1's to settable bits to clear errors */
184 *(vusp)POLARIS_W_STATUS = 0x7800;
185 mb();
186 *(vusp)POLARIS_W_STATUS;
187 }
189 void
190 polaris_machine_check(unsigned long vector, unsigned long la_ptr,
191 struct pt_regs * regs)
192 {
193 /* Clear the error before any reporting. */
194 mb();
195 mb();
196 draina();
197 polaris_pci_clr_err();
198 wrmces(0x7);
199 mb();
201 process_mcheck_info(vector, la_ptr, regs, "POLARIS",
202 mcheck_expected(0));
203 }