ia64/linux-2.6.18-xen.hg

view arch/alpha/kernel/err_ev7.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/err_ev7.c
3 *
4 * Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation)
5 *
6 * Error handling code supporting Alpha systems
7 */
9 #include <linux/init.h>
10 #include <linux/pci.h>
11 #include <linux/sched.h>
13 #include <asm/io.h>
14 #include <asm/hwrpb.h>
15 #include <asm/smp.h>
16 #include <asm/err_common.h>
17 #include <asm/err_ev7.h>
19 #include "err_impl.h"
20 #include "proto.h"
22 struct ev7_lf_subpackets *
23 ev7_collect_logout_frame_subpackets(struct el_subpacket *el_ptr,
24 struct ev7_lf_subpackets *lf_subpackets)
25 {
26 struct el_subpacket *subpacket;
27 int i;
29 /*
30 * A Marvel machine check frame is always packaged in an
31 * el_subpacket of class HEADER, type LOGOUT_FRAME.
32 */
33 if (el_ptr->class != EL_CLASS__HEADER ||
34 el_ptr->type != EL_TYPE__HEADER__LOGOUT_FRAME)
35 return NULL;
37 /*
38 * It is a logout frame header. Look at the one subpacket.
39 */
40 el_ptr = (struct el_subpacket *)
41 ((unsigned long)el_ptr + el_ptr->length);
43 /*
44 * It has to be class PAL, type LOGOUT_FRAME.
45 */
46 if (el_ptr->class != EL_CLASS__PAL ||
47 el_ptr->type != EL_TYPE__PAL__LOGOUT_FRAME)
48 return NULL;
50 lf_subpackets->logout = (struct ev7_pal_logout_subpacket *)
51 el_ptr->by_type.raw.data_start;
53 /*
54 * Process the subpackets.
55 */
56 subpacket = (struct el_subpacket *)
57 ((unsigned long)el_ptr + el_ptr->length);
58 for (i = 0;
59 subpacket && i < lf_subpackets->logout->subpacket_count;
60 subpacket = (struct el_subpacket *)
61 ((unsigned long)subpacket + subpacket->length), i++) {
62 /*
63 * All subpackets should be class PAL.
64 */
65 if (subpacket->class != EL_CLASS__PAL) {
66 printk("%s**UNEXPECTED SUBPACKET CLASS %d "
67 "IN LOGOUT FRAME (packet %d\n",
68 err_print_prefix, subpacket->class, i);
69 return NULL;
70 }
72 /*
73 * Remember the subpacket.
74 */
75 switch(subpacket->type) {
76 case EL_TYPE__PAL__EV7_PROCESSOR:
77 lf_subpackets->ev7 =
78 (struct ev7_pal_processor_subpacket *)
79 subpacket->by_type.raw.data_start;
80 break;
82 case EL_TYPE__PAL__EV7_RBOX:
83 lf_subpackets->rbox = (struct ev7_pal_rbox_subpacket *)
84 subpacket->by_type.raw.data_start;
85 break;
87 case EL_TYPE__PAL__EV7_ZBOX:
88 lf_subpackets->zbox = (struct ev7_pal_zbox_subpacket *)
89 subpacket->by_type.raw.data_start;
90 break;
92 case EL_TYPE__PAL__EV7_IO:
93 lf_subpackets->io = (struct ev7_pal_io_subpacket *)
94 subpacket->by_type.raw.data_start;
95 break;
97 case EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE:
98 case EL_TYPE__PAL__ENV__AIRMOVER_FAN:
99 case EL_TYPE__PAL__ENV__VOLTAGE:
100 case EL_TYPE__PAL__ENV__INTRUSION:
101 case EL_TYPE__PAL__ENV__POWER_SUPPLY:
102 case EL_TYPE__PAL__ENV__LAN:
103 case EL_TYPE__PAL__ENV__HOT_PLUG:
104 lf_subpackets->env[ev7_lf_env_index(subpacket->type)] =
105 (struct ev7_pal_environmental_subpacket *)
106 subpacket->by_type.raw.data_start;
107 break;
109 default:
110 /*
111 * Don't know what kind of frame this is.
112 */
113 return NULL;
114 }
115 }
117 return lf_subpackets;
118 }
120 void
121 ev7_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
122 {
123 struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
124 char *saved_err_prefix = err_print_prefix;
126 /*
127 * Sync the processor
128 */
129 mb();
130 draina();
132 err_print_prefix = KERN_CRIT;
133 printk("%s*CPU %s Error (Vector 0x%x) reported on CPU %d\n",
134 err_print_prefix,
135 (vector == SCB_Q_PROCERR) ? "Correctable" : "Uncorrectable",
136 (unsigned int)vector, (int)smp_processor_id());
137 el_process_subpacket(el_ptr);
138 err_print_prefix = saved_err_prefix;
140 /*
141 * Release the logout frame
142 */
143 wrmces(0x7);
144 mb();
145 }
147 static char *el_ev7_processor_subpacket_annotation[] = {
148 "Subpacket Header", "I_STAT", "DC_STAT",
149 "C_ADDR", "C_SYNDROME_1", "C_SYNDROME_0",
150 "C_STAT", "C_STS", "MM_STAT",
151 "EXC_ADDR", "IER_CM", "ISUM",
152 "PAL_BASE", "I_CTL", "PROCESS_CONTEXT",
153 "CBOX_CTL", "CBOX_STP_CTL", "CBOX_ACC_CTL",
154 "CBOX_LCL_SET", "CBOX_GLB_SET", "BBOX_CTL",
155 "BBOX_ERR_STS", "BBOX_ERR_IDX", "CBOX_DDP_ERR_STS",
156 "BBOX_DAT_RMP", NULL
157 };
159 static char *el_ev7_zbox_subpacket_annotation[] = {
160 "Subpacket Header",
161 "ZBOX(0): DRAM_ERR_STATUS_2 / DRAM_ERR_STATUS_1",
162 "ZBOX(0): DRAM_ERROR_CTL / DRAM_ERR_STATUS_3",
163 "ZBOX(0): DIFT_TIMEOUT / DRAM_ERR_ADR",
164 "ZBOX(0): FRC_ERR_ADR / DRAM_MAPPER_CTL",
165 "ZBOX(0): reserved / DIFT_ERR_STATUS",
166 "ZBOX(1): DRAM_ERR_STATUS_2 / DRAM_ERR_STATUS_1",
167 "ZBOX(1): DRAM_ERROR_CTL / DRAM_ERR_STATUS_3",
168 "ZBOX(1): DIFT_TIMEOUT / DRAM_ERR_ADR",
169 "ZBOX(1): FRC_ERR_ADR / DRAM_MAPPER_CTL",
170 "ZBOX(1): reserved / DIFT_ERR_STATUS",
171 "CBOX_CTL", "CBOX_STP_CTL",
172 "ZBOX(0)_ERROR_PA", "ZBOX(1)_ERROR_PA",
173 "ZBOX(0)_ORED_SYNDROME","ZBOX(1)_ORED_SYNDROME",
174 NULL
175 };
177 static char *el_ev7_rbox_subpacket_annotation[] = {
178 "Subpacket Header", "RBOX_CFG", "RBOX_N_CFG",
179 "RBOX_S_CFG", "RBOX_E_CFG", "RBOX_W_CFG",
180 "RBOX_N_ERR", "RBOX_S_ERR", "RBOX_E_ERR",
181 "RBOX_W_ERR", "RBOX_IO_CFG", "RBOX_IO_ERR",
182 "RBOX_L_ERR", "RBOX_WHOAMI", "RBOX_IMASL",
183 "RBOX_INTQ", "RBOX_INT", NULL
184 };
186 static char *el_ev7_io_subpacket_annotation[] = {
187 "Subpacket Header", "IO_ASIC_REV", "IO_SYS_REV",
188 "IO7_UPH", "HPI_CTL", "CRD_CTL",
189 "HEI_CTL", "PO7_ERROR_SUM","PO7_UNCRR_SYM",
190 "PO7_CRRCT_SYM", "PO7_UGBGE_SYM","PO7_ERR_PKT0",
191 "PO7_ERR_PKT1", "reserved", "reserved",
192 "PO0_ERR_SUM", "PO0_TLB_ERR", "PO0_SPL_COMPLT",
193 "PO0_TRANS_SUM", "PO0_FIRST_ERR","PO0_MULT_ERR",
194 "DM CSR PH", "DM CSR PH", "DM CSR PH",
195 "DM CSR PH", "reserved",
196 "PO1_ERR_SUM", "PO1_TLB_ERR", "PO1_SPL_COMPLT",
197 "PO1_TRANS_SUM", "PO1_FIRST_ERR","PO1_MULT_ERR",
198 "DM CSR PH", "DM CSR PH", "DM CSR PH",
199 "DM CSR PH", "reserved",
200 "PO2_ERR_SUM", "PO2_TLB_ERR", "PO2_SPL_COMPLT",
201 "PO2_TRANS_SUM", "PO2_FIRST_ERR","PO2_MULT_ERR",
202 "DM CSR PH", "DM CSR PH", "DM CSR PH",
203 "DM CSR PH", "reserved",
204 "PO3_ERR_SUM", "PO3_TLB_ERR", "PO3_SPL_COMPLT",
205 "PO3_TRANS_SUM", "PO3_FIRST_ERR","PO3_MULT_ERR",
206 "DM CSR PH", "DM CSR PH", "DM CSR PH",
207 "DM CSR PH", "reserved",
208 NULL
209 };
211 static struct el_subpacket_annotation el_ev7_pal_annotations[] = {
212 SUBPACKET_ANNOTATION(EL_CLASS__PAL,
213 EL_TYPE__PAL__EV7_PROCESSOR,
214 1,
215 "EV7 Processor Subpacket",
216 el_ev7_processor_subpacket_annotation),
217 SUBPACKET_ANNOTATION(EL_CLASS__PAL,
218 EL_TYPE__PAL__EV7_ZBOX,
219 1,
220 "EV7 ZBOX Subpacket",
221 el_ev7_zbox_subpacket_annotation),
222 SUBPACKET_ANNOTATION(EL_CLASS__PAL,
223 EL_TYPE__PAL__EV7_RBOX,
224 1,
225 "EV7 RBOX Subpacket",
226 el_ev7_rbox_subpacket_annotation),
227 SUBPACKET_ANNOTATION(EL_CLASS__PAL,
228 EL_TYPE__PAL__EV7_IO,
229 1,
230 "EV7 IO Subpacket",
231 el_ev7_io_subpacket_annotation)
232 };
234 static struct el_subpacket *
235 ev7_process_pal_subpacket(struct el_subpacket *header)
236 {
237 struct ev7_pal_subpacket *packet;
239 if (header->class != EL_CLASS__PAL) {
240 printk("%s ** Unexpected header CLASS %d TYPE %d, aborting\n",
241 err_print_prefix,
242 header->class, header->type);
243 return NULL;
244 }
246 packet = (struct ev7_pal_subpacket *)header->by_type.raw.data_start;
248 switch(header->type) {
249 case EL_TYPE__PAL__LOGOUT_FRAME:
250 printk("%s*** MCHK occurred on LPID %ld (RBOX %lx)\n",
251 err_print_prefix,
252 packet->by_type.logout.whami,
253 packet->by_type.logout.rbox_whami);
254 el_print_timestamp(&packet->by_type.logout.timestamp);
255 printk("%s EXC_ADDR: %016lx\n"
256 " HALT_CODE: %lx\n",
257 err_print_prefix,
258 packet->by_type.logout.exc_addr,
259 packet->by_type.logout.halt_code);
260 el_process_subpackets(header,
261 packet->by_type.logout.subpacket_count);
262 break;
263 default:
264 printk("%s ** PAL TYPE %d SUBPACKET\n",
265 err_print_prefix,
266 header->type);
267 el_annotate_subpacket(header);
268 break;
269 }
271 return (struct el_subpacket *)((unsigned long)header + header->length);
272 }
274 struct el_subpacket_handler ev7_pal_subpacket_handler =
275 SUBPACKET_HANDLER_INIT(EL_CLASS__PAL, ev7_process_pal_subpacket);
277 void
278 ev7_register_error_handlers(void)
279 {
280 int i;
282 for (i = 0; i < ARRAY_SIZE(el_ev7_pal_annotations); i++)
283 cdl_register_subpacket_annotation(&el_ev7_pal_annotations[i]);
285 cdl_register_subpacket_handler(&ev7_pal_subpacket_handler);
286 }