ia64/linux-2.6.18-xen.hg

view arch/alpha/kernel/sys_jensen.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/sys_jensen.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Copyright (C) 1998, 1999 Richard Henderson
6 *
7 * Code supporting the Jensen.
8 */
10 #include <linux/kernel.h>
11 #include <linux/types.h>
12 #include <linux/mm.h>
13 #include <linux/sched.h>
14 #include <linux/pci.h>
15 #include <linux/init.h>
17 #include <asm/ptrace.h>
18 #include <asm/system.h>
20 #define __EXTERN_INLINE inline
21 #include <asm/io.h>
22 #include <asm/jensen.h>
23 #undef __EXTERN_INLINE
25 #include <asm/dma.h>
26 #include <asm/irq.h>
27 #include <asm/mmu_context.h>
28 #include <asm/pgtable.h>
29 #include <asm/tlbflush.h>
31 #include "proto.h"
32 #include "irq_impl.h"
33 #include "pci_impl.h"
34 #include "machvec_impl.h"
37 /*
38 * Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
39 * 0x9X0 for the local motherboard interrupts.
40 *
41 * Note especially that those local interrupts CANNOT be masked,
42 * which causes much of the pain below...
43 *
44 * 0x660 - NMI
45 *
46 * 0x800 - IRQ0 interval timer (not used, as we use the RTC timer)
47 * 0x810 - IRQ1 line printer (duh..)
48 * 0x860 - IRQ6 floppy disk
49 *
50 * 0x900 - COM1
51 * 0x920 - COM2
52 * 0x980 - keyboard
53 * 0x990 - mouse
54 *
55 * PCI-based systems are more sane: they don't have the local
56 * interrupts at all, and have only normal PCI interrupts from
57 * devices. Happily it's easy enough to do a sane mapping from the
58 * Jensen.
59 *
60 * Note that this means that we may have to do a hardware
61 * "local_op" to a different interrupt than we report to the rest of the
62 * world.
63 */
65 static unsigned int
66 jensen_local_startup(unsigned int irq)
67 {
68 /* the parport is really hw IRQ 1, silly Jensen. */
69 if (irq == 7)
70 i8259a_startup_irq(1);
71 else
72 /*
73 * For all true local interrupts, set the flag that prevents
74 * the IPL from being dropped during handler processing.
75 */
76 if (irq_desc[irq].action)
77 irq_desc[irq].action->flags |= IRQF_DISABLED;
78 return 0;
79 }
81 static void
82 jensen_local_shutdown(unsigned int irq)
83 {
84 /* the parport is really hw IRQ 1, silly Jensen. */
85 if (irq == 7)
86 i8259a_disable_irq(1);
87 }
89 static void
90 jensen_local_enable(unsigned int irq)
91 {
92 /* the parport is really hw IRQ 1, silly Jensen. */
93 if (irq == 7)
94 i8259a_enable_irq(1);
95 }
97 static void
98 jensen_local_disable(unsigned int irq)
99 {
100 /* the parport is really hw IRQ 1, silly Jensen. */
101 if (irq == 7)
102 i8259a_disable_irq(1);
103 }
105 static void
106 jensen_local_ack(unsigned int irq)
107 {
108 /* the parport is really hw IRQ 1, silly Jensen. */
109 if (irq == 7)
110 i8259a_mask_and_ack_irq(1);
111 }
113 static void
114 jensen_local_end(unsigned int irq)
115 {
116 /* the parport is really hw IRQ 1, silly Jensen. */
117 if (irq == 7)
118 i8259a_end_irq(1);
119 }
121 static struct hw_interrupt_type jensen_local_irq_type = {
122 .typename = "LOCAL",
123 .startup = jensen_local_startup,
124 .shutdown = jensen_local_shutdown,
125 .enable = jensen_local_enable,
126 .disable = jensen_local_disable,
127 .ack = jensen_local_ack,
128 .end = jensen_local_end,
129 };
131 static void
132 jensen_device_interrupt(unsigned long vector, struct pt_regs * regs)
133 {
134 int irq;
136 switch (vector) {
137 case 0x660:
138 printk("Whee.. NMI received. Probable hardware error\n");
139 printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
140 return;
142 /* local device interrupts: */
143 case 0x900: irq = 4; break; /* com1 -> irq 4 */
144 case 0x920: irq = 3; break; /* com2 -> irq 3 */
145 case 0x980: irq = 1; break; /* kbd -> irq 1 */
146 case 0x990: irq = 9; break; /* mouse -> irq 9 */
148 default:
149 if (vector > 0x900) {
150 printk("Unknown local interrupt %lx\n", vector);
151 return;
152 }
154 irq = (vector - 0x800) >> 4;
155 if (irq == 1)
156 irq = 7;
157 break;
158 }
160 /* If there is no handler yet... */
161 if (irq_desc[irq].action == NULL) {
162 /* If it is a local interrupt that cannot be masked... */
163 if (vector >= 0x900)
164 {
165 /* Clear keyboard/mouse state */
166 inb(0x64);
167 inb(0x60);
168 /* Reset serial ports */
169 inb(0x3fa);
170 inb(0x2fa);
171 outb(0x0c, 0x3fc);
172 outb(0x0c, 0x2fc);
173 /* Clear NMI */
174 outb(0,0x61);
175 outb(0,0x461);
176 }
177 }
179 #if 0
180 /* A useful bit of code to find out if an interrupt is going wild. */
181 {
182 static unsigned int last_msg = 0, last_cc = 0;
183 static int last_irq = -1, count = 0;
184 unsigned int cc;
186 __asm __volatile("rpcc %0" : "=r"(cc));
187 ++count;
188 #define JENSEN_CYCLES_PER_SEC (150000000)
189 if (cc - last_msg > ((JENSEN_CYCLES_PER_SEC) * 3) ||
190 irq != last_irq) {
191 printk(KERN_CRIT " irq %d count %d cc %u @ %lx\n",
192 irq, count, cc-last_cc, regs->pc);
193 count = 0;
194 last_msg = cc;
195 last_irq = irq;
196 }
197 last_cc = cc;
198 }
199 #endif
201 handle_irq(irq, regs);
202 }
204 static void __init
205 jensen_init_irq(void)
206 {
207 init_i8259a_irqs();
209 irq_desc[1].chip = &jensen_local_irq_type;
210 irq_desc[4].chip = &jensen_local_irq_type;
211 irq_desc[3].chip = &jensen_local_irq_type;
212 irq_desc[7].chip = &jensen_local_irq_type;
213 irq_desc[9].chip = &jensen_local_irq_type;
215 common_init_isa_dma();
216 }
218 static void __init
219 jensen_init_arch(void)
220 {
221 struct pci_controller *hose;
222 #ifdef CONFIG_PCI
223 static struct pci_dev fake_isa_bridge = { .dma_mask = 0xffffffffUL, };
225 isa_bridge = &fake_isa_bridge;
226 #endif
228 /* Create a hose so that we can report i/o base addresses to
229 userland. */
231 pci_isa_hose = hose = alloc_pci_controller();
232 hose->io_space = &ioport_resource;
233 hose->mem_space = &iomem_resource;
234 hose->index = 0;
236 hose->sparse_mem_base = EISA_MEM - IDENT_ADDR;
237 hose->dense_mem_base = 0;
238 hose->sparse_io_base = EISA_IO - IDENT_ADDR;
239 hose->dense_io_base = 0;
241 hose->sg_isa = hose->sg_pci = NULL;
242 __direct_map_base = 0;
243 __direct_map_size = 0xffffffff;
244 }
246 static void
247 jensen_machine_check (u64 vector, u64 la, struct pt_regs *regs)
248 {
249 printk(KERN_CRIT "Machine check\n");
250 }
253 /*
254 * The System Vector
255 */
257 struct alpha_machine_vector jensen_mv __initmv = {
258 .vector_name = "Jensen",
259 DO_EV4_MMU,
260 IO_LITE(JENSEN,jensen),
261 .machine_check = jensen_machine_check,
262 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
263 .rtc_port = 0x170,
265 .nr_irqs = 16,
266 .device_interrupt = jensen_device_interrupt,
268 .init_arch = jensen_init_arch,
269 .init_irq = jensen_init_irq,
270 .init_rtc = common_init_rtc,
271 .init_pci = NULL,
272 .kill_arch = NULL,
273 };
274 ALIAS_MV(jensen)