ia64/linux-2.6.18-xen.hg

view arch/alpha/kernel/irq_alpha.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 * Alpha specific irq code.
3 */
5 #include <linux/init.h>
6 #include <linux/sched.h>
7 #include <linux/irq.h>
8 #include <linux/kernel_stat.h>
10 #include <asm/machvec.h>
11 #include <asm/dma.h>
13 #include "proto.h"
14 #include "irq_impl.h"
16 /* Hack minimum IPL during interrupt processing for broken hardware. */
17 #ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
18 int __min_ipl;
19 #endif
21 /*
22 * Performance counter hook. A module can override this to
23 * do something useful.
24 */
25 static void
26 dummy_perf(unsigned long vector, struct pt_regs *regs)
27 {
28 irq_err_count++;
29 printk(KERN_CRIT "Performance counter interrupt!\n");
30 }
32 void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf;
34 /*
35 * The main interrupt entry point.
36 */
38 asmlinkage void
39 do_entInt(unsigned long type, unsigned long vector,
40 unsigned long la_ptr, struct pt_regs *regs)
41 {
42 switch (type) {
43 case 0:
44 #ifdef CONFIG_SMP
45 handle_ipi(regs);
46 return;
47 #else
48 irq_err_count++;
49 printk(KERN_CRIT "Interprocessor interrupt? "
50 "You must be kidding!\n");
51 #endif
52 break;
53 case 1:
54 #ifdef CONFIG_SMP
55 {
56 long cpu;
58 local_irq_disable();
59 smp_percpu_timer_interrupt(regs);
60 cpu = smp_processor_id();
61 if (cpu != boot_cpuid) {
62 kstat_cpu(cpu).irqs[RTC_IRQ]++;
63 } else {
64 handle_irq(RTC_IRQ, regs);
65 }
66 }
67 #else
68 handle_irq(RTC_IRQ, regs);
69 #endif
70 return;
71 case 2:
72 alpha_mv.machine_check(vector, la_ptr, regs);
73 return;
74 case 3:
75 alpha_mv.device_interrupt(vector, regs);
76 return;
77 case 4:
78 perf_irq(la_ptr, regs);
79 return;
80 default:
81 printk(KERN_CRIT "Hardware intr %ld %lx? Huh?\n",
82 type, vector);
83 }
84 printk(KERN_CRIT "PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
85 }
87 void __init
88 common_init_isa_dma(void)
89 {
90 outb(0, DMA1_RESET_REG);
91 outb(0, DMA2_RESET_REG);
92 outb(0, DMA1_CLR_MASK_REG);
93 outb(0, DMA2_CLR_MASK_REG);
94 }
96 void __init
97 init_IRQ(void)
98 {
99 /* Just in case the platform init_irq() causes interrupts/mchecks
100 (as is the case with RAWHIDE, at least). */
101 wrent(entInt, 0);
103 alpha_mv.init_irq();
104 }
106 /*
107 * machine error checks
108 */
109 #define MCHK_K_TPERR 0x0080
110 #define MCHK_K_TCPERR 0x0082
111 #define MCHK_K_HERR 0x0084
112 #define MCHK_K_ECC_C 0x0086
113 #define MCHK_K_ECC_NC 0x0088
114 #define MCHK_K_OS_BUGCHECK 0x008A
115 #define MCHK_K_PAL_BUGCHECK 0x0090
117 #ifndef CONFIG_SMP
118 struct mcheck_info __mcheck_info;
119 #endif
121 void
122 process_mcheck_info(unsigned long vector, unsigned long la_ptr,
123 struct pt_regs *regs, const char *machine,
124 int expected)
125 {
126 struct el_common *mchk_header;
127 const char *reason;
129 /*
130 * See if the machine check is due to a badaddr() and if so,
131 * ignore it.
132 */
134 #ifdef CONFIG_VERBOSE_MCHECK
135 if (alpha_verbose_mcheck > 1) {
136 printk(KERN_CRIT "%s machine check %s\n", machine,
137 expected ? "expected." : "NOT expected!!!");
138 }
139 #endif
141 if (expected) {
142 int cpu = smp_processor_id();
143 mcheck_expected(cpu) = 0;
144 mcheck_taken(cpu) = 1;
145 return;
146 }
148 mchk_header = (struct el_common *)la_ptr;
150 printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%x\n",
151 machine, vector, regs->pc, mchk_header->code);
153 switch (mchk_header->code) {
154 /* Machine check reasons. Defined according to PALcode sources. */
155 case 0x80: reason = "tag parity error"; break;
156 case 0x82: reason = "tag control parity error"; break;
157 case 0x84: reason = "generic hard error"; break;
158 case 0x86: reason = "correctable ECC error"; break;
159 case 0x88: reason = "uncorrectable ECC error"; break;
160 case 0x8A: reason = "OS-specific PAL bugcheck"; break;
161 case 0x90: reason = "callsys in kernel mode"; break;
162 case 0x96: reason = "i-cache read retryable error"; break;
163 case 0x98: reason = "processor detected hard error"; break;
165 /* System specific (these are for Alcor, at least): */
166 case 0x202: reason = "system detected hard error"; break;
167 case 0x203: reason = "system detected uncorrectable ECC error"; break;
168 case 0x204: reason = "SIO SERR occurred on PCI bus"; break;
169 case 0x205: reason = "parity error detected by core logic"; break;
170 case 0x206: reason = "SIO IOCHK occurred on ISA bus"; break;
171 case 0x207: reason = "non-existent memory error"; break;
172 case 0x208: reason = "MCHK_K_DCSR"; break;
173 case 0x209: reason = "PCI SERR detected"; break;
174 case 0x20b: reason = "PCI data parity error detected"; break;
175 case 0x20d: reason = "PCI address parity error detected"; break;
176 case 0x20f: reason = "PCI master abort error"; break;
177 case 0x211: reason = "PCI target abort error"; break;
178 case 0x213: reason = "scatter/gather PTE invalid error"; break;
179 case 0x215: reason = "flash ROM write error"; break;
180 case 0x217: reason = "IOA timeout detected"; break;
181 case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
182 case 0x21b: reason = "EISA fail-safe timer timeout"; break;
183 case 0x21d: reason = "EISA bus time-out"; break;
184 case 0x21f: reason = "EISA software generated NMI"; break;
185 case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
186 default: reason = "unknown"; break;
187 }
189 printk(KERN_CRIT "machine check type: %s%s\n",
190 reason, mchk_header->retry ? " (retryable)" : "");
192 dik_show_regs(regs, NULL);
194 #ifdef CONFIG_VERBOSE_MCHECK
195 if (alpha_verbose_mcheck > 1) {
196 /* Dump the logout area to give all info. */
197 unsigned long *ptr = (unsigned long *)la_ptr;
198 long i;
199 for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
200 printk(KERN_CRIT " +%8lx %016lx %016lx\n",
201 i*sizeof(long), ptr[i], ptr[i+1]);
202 }
203 }
204 #endif /* CONFIG_VERBOSE_MCHECK */
205 }
207 /*
208 * The special RTC interrupt type. The interrupt itself was
209 * processed by PALcode, and comes in via entInt vector 1.
210 */
212 static void rtc_enable_disable(unsigned int irq) { }
213 static unsigned int rtc_startup(unsigned int irq) { return 0; }
215 struct irqaction timer_irqaction = {
216 .handler = timer_interrupt,
217 .flags = IRQF_DISABLED,
218 .name = "timer",
219 };
221 static struct hw_interrupt_type rtc_irq_type = {
222 .typename = "RTC",
223 .startup = rtc_startup,
224 .shutdown = rtc_enable_disable,
225 .enable = rtc_enable_disable,
226 .disable = rtc_enable_disable,
227 .ack = rtc_enable_disable,
228 .end = rtc_enable_disable,
229 };
231 void __init
232 init_rtc_irq(void)
233 {
234 irq_desc[RTC_IRQ].status = IRQ_DISABLED;
235 irq_desc[RTC_IRQ].chip = &rtc_irq_type;
236 setup_irq(RTC_IRQ, &timer_irqaction);
237 }
239 /* Dummy irqactions. */
240 struct irqaction isa_cascade_irqaction = {
241 .handler = no_action,
242 .name = "isa-cascade"
243 };
245 struct irqaction timer_cascade_irqaction = {
246 .handler = no_action,
247 .name = "timer-cascade"
248 };
250 struct irqaction halt_switch_irqaction = {
251 .handler = no_action,
252 .name = "halt-switch"
253 };