ia64/linux-2.6.18-xen.hg

view drivers/acpi/utilities/utresrc.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 *
3 * Module Name: utresrc - Resource managment utilities
4 *
5 ******************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
44 #include <acpi/acpi.h>
45 #include <acpi/amlresrc.h>
47 #define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME("utresrc")
50 #if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
51 /*
52 * Strings used to decode resource descriptors.
53 * Used by both the disasssembler and the debugger resource dump routines
54 */
55 const char *acpi_gbl_bm_decode[] = {
56 "NotBusMaster",
57 "BusMaster"
58 };
60 const char *acpi_gbl_config_decode[] = {
61 "0 - Good Configuration",
62 "1 - Acceptable Configuration",
63 "2 - Suboptimal Configuration",
64 "3 - ***Invalid Configuration***",
65 };
67 const char *acpi_gbl_consume_decode[] = {
68 "ResourceProducer",
69 "ResourceConsumer"
70 };
72 const char *acpi_gbl_dec_decode[] = {
73 "PosDecode",
74 "SubDecode"
75 };
77 const char *acpi_gbl_he_decode[] = {
78 "Level",
79 "Edge"
80 };
82 const char *acpi_gbl_io_decode[] = {
83 "Decode10",
84 "Decode16"
85 };
87 const char *acpi_gbl_ll_decode[] = {
88 "ActiveHigh",
89 "ActiveLow"
90 };
92 const char *acpi_gbl_max_decode[] = {
93 "MaxNotFixed",
94 "MaxFixed"
95 };
97 const char *acpi_gbl_mem_decode[] = {
98 "NonCacheable",
99 "Cacheable",
100 "WriteCombining",
101 "Prefetchable"
102 };
104 const char *acpi_gbl_min_decode[] = {
105 "MinNotFixed",
106 "MinFixed"
107 };
109 const char *acpi_gbl_mtp_decode[] = {
110 "AddressRangeMemory",
111 "AddressRangeReserved",
112 "AddressRangeACPI",
113 "AddressRangeNVS"
114 };
116 const char *acpi_gbl_rng_decode[] = {
117 "InvalidRanges",
118 "NonISAOnlyRanges",
119 "ISAOnlyRanges",
120 "EntireRange"
121 };
123 const char *acpi_gbl_rw_decode[] = {
124 "ReadOnly",
125 "ReadWrite"
126 };
128 const char *acpi_gbl_shr_decode[] = {
129 "Exclusive",
130 "Shared"
131 };
133 const char *acpi_gbl_siz_decode[] = {
134 "Transfer8",
135 "Transfer8_16",
136 "Transfer16",
137 "InvalidSize"
138 };
140 const char *acpi_gbl_trs_decode[] = {
141 "DenseTranslation",
142 "SparseTranslation"
143 };
145 const char *acpi_gbl_ttp_decode[] = {
146 "TypeStatic",
147 "TypeTranslation"
148 };
150 const char *acpi_gbl_typ_decode[] = {
151 "Compatibility",
152 "TypeA",
153 "TypeB",
154 "TypeF"
155 };
157 #endif
159 /*
160 * Base sizes of the raw AML resource descriptors, indexed by resource type.
161 * Zero indicates a reserved (and therefore invalid) resource type.
162 */
163 const u8 acpi_gbl_resource_aml_sizes[] = {
164 /* Small descriptors */
166 0,
167 0,
168 0,
169 0,
170 ACPI_AML_SIZE_SMALL(struct aml_resource_irq),
171 ACPI_AML_SIZE_SMALL(struct aml_resource_dma),
172 ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent),
173 ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
174 ACPI_AML_SIZE_SMALL(struct aml_resource_io),
175 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
176 0,
177 0,
178 0,
179 0,
180 ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small),
181 ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag),
183 /* Large descriptors */
185 0,
186 ACPI_AML_SIZE_LARGE(struct aml_resource_memory24),
187 ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register),
188 0,
189 ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large),
190 ACPI_AML_SIZE_LARGE(struct aml_resource_memory32),
191 ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32),
192 ACPI_AML_SIZE_LARGE(struct aml_resource_address32),
193 ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
194 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
195 ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
196 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64)
197 };
199 /*
200 * Resource types, used to validate the resource length field.
201 * The length of fixed-length types must match exactly, variable
202 * lengths must meet the minimum required length, etc.
203 * Zero indicates a reserved (and therefore invalid) resource type.
204 */
205 static const u8 acpi_gbl_resource_types[] = {
206 /* Small descriptors */
208 0,
209 0,
210 0,
211 0,
212 ACPI_SMALL_VARIABLE_LENGTH,
213 ACPI_FIXED_LENGTH,
214 ACPI_SMALL_VARIABLE_LENGTH,
215 ACPI_FIXED_LENGTH,
216 ACPI_FIXED_LENGTH,
217 ACPI_FIXED_LENGTH,
218 0,
219 0,
220 0,
221 0,
222 ACPI_VARIABLE_LENGTH,
223 ACPI_FIXED_LENGTH,
225 /* Large descriptors */
227 0,
228 ACPI_FIXED_LENGTH,
229 ACPI_FIXED_LENGTH,
230 0,
231 ACPI_VARIABLE_LENGTH,
232 ACPI_FIXED_LENGTH,
233 ACPI_FIXED_LENGTH,
234 ACPI_VARIABLE_LENGTH,
235 ACPI_VARIABLE_LENGTH,
236 ACPI_VARIABLE_LENGTH,
237 ACPI_VARIABLE_LENGTH,
238 ACPI_FIXED_LENGTH
239 };
241 /*******************************************************************************
242 *
243 * FUNCTION: acpi_ut_walk_aml_resources
244 *
245 * PARAMETERS: Aml - Pointer to the raw AML resource template
246 * aml_length - Length of the entire template
247 * user_function - Called once for each descriptor found. If
248 * NULL, a pointer to the end_tag is returned
249 * Context - Passed to user_function
250 *
251 * RETURN: Status
252 *
253 * DESCRIPTION: Walk a raw AML resource list(buffer). User function called
254 * once for each resource found.
255 *
256 ******************************************************************************/
258 acpi_status
259 acpi_ut_walk_aml_resources(u8 * aml,
260 acpi_size aml_length,
261 acpi_walk_aml_callback user_function, void **context)
262 {
263 acpi_status status;
264 u8 *end_aml;
265 u8 resource_index;
266 u32 length;
267 u32 offset = 0;
269 ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
271 /* The absolute minimum resource template is one end_tag descriptor */
273 if (aml_length < sizeof(struct aml_resource_end_tag)) {
274 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
275 }
277 /* Point to the end of the resource template buffer */
279 end_aml = aml + aml_length;
281 /* Walk the byte list, abort on any invalid descriptor type or length */
283 while (aml < end_aml) {
285 /* Validate the Resource Type and Resource Length */
287 status = acpi_ut_validate_resource(aml, &resource_index);
288 if (ACPI_FAILURE(status)) {
289 return_ACPI_STATUS(status);
290 }
292 /* Get the length of this descriptor */
294 length = acpi_ut_get_descriptor_length(aml);
296 /* Invoke the user function */
298 if (user_function) {
299 status =
300 user_function(aml, length, offset, resource_index,
301 context);
302 if (ACPI_FAILURE(status)) {
303 return (status);
304 }
305 }
307 /* An end_tag descriptor terminates this resource template */
309 if (acpi_ut_get_resource_type(aml) ==
310 ACPI_RESOURCE_NAME_END_TAG) {
311 /*
312 * There must be at least one more byte in the buffer for
313 * the 2nd byte of the end_tag
314 */
315 if ((aml + 1) >= end_aml) {
316 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
317 }
319 /* Return the pointer to the end_tag if requested */
321 if (!user_function) {
322 *context = aml;
323 }
325 /* Normal exit */
327 return_ACPI_STATUS(AE_OK);
328 }
330 aml += length;
331 offset += length;
332 }
334 /* Did not find an end_tag descriptor */
336 return (AE_AML_NO_RESOURCE_END_TAG);
337 }
339 /*******************************************************************************
340 *
341 * FUNCTION: acpi_ut_validate_resource
342 *
343 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
344 * return_index - Where the resource index is returned. NULL
345 * if the index is not required.
346 *
347 * RETURN: Status, and optionally the Index into the global resource tables
348 *
349 * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
350 * Type and Resource Length. Returns an index into the global
351 * resource information/dispatch tables for later use.
352 *
353 ******************************************************************************/
355 acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
356 {
357 u8 resource_type;
358 u8 resource_index;
359 acpi_rs_length resource_length;
360 acpi_rs_length minimum_resource_length;
362 ACPI_FUNCTION_ENTRY();
364 /*
365 * 1) Validate the resource_type field (Byte 0)
366 */
367 resource_type = ACPI_GET8(aml);
369 /*
370 * Byte 0 contains the descriptor name (Resource Type)
371 * Examine the large/small bit in the resource header
372 */
373 if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
375 /* Verify the large resource type (name) against the max */
377 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
378 return (AE_AML_INVALID_RESOURCE_TYPE);
379 }
381 /*
382 * Large Resource Type -- bits 6:0 contain the name
383 * Translate range 0x80-0x8B to index range 0x10-0x1B
384 */
385 resource_index = (u8) (resource_type - 0x70);
386 } else {
387 /*
388 * Small Resource Type -- bits 6:3 contain the name
389 * Shift range to index range 0x00-0x0F
390 */
391 resource_index = (u8)
392 ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
393 }
395 /* Check validity of the resource type, zero indicates name is invalid */
397 if (!acpi_gbl_resource_types[resource_index]) {
398 return (AE_AML_INVALID_RESOURCE_TYPE);
399 }
401 /*
402 * 2) Validate the resource_length field. This ensures that the length
403 * is at least reasonable, and guarantees that it is non-zero.
404 */
405 resource_length = acpi_ut_get_resource_length(aml);
406 minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
408 /* Validate based upon the type of resource - fixed length or variable */
410 switch (acpi_gbl_resource_types[resource_index]) {
411 case ACPI_FIXED_LENGTH:
413 /* Fixed length resource, length must match exactly */
415 if (resource_length != minimum_resource_length) {
416 return (AE_AML_BAD_RESOURCE_LENGTH);
417 }
418 break;
420 case ACPI_VARIABLE_LENGTH:
422 /* Variable length resource, length must be at least the minimum */
424 if (resource_length < minimum_resource_length) {
425 return (AE_AML_BAD_RESOURCE_LENGTH);
426 }
427 break;
429 case ACPI_SMALL_VARIABLE_LENGTH:
431 /* Small variable length resource, length can be (Min) or (Min-1) */
433 if ((resource_length > minimum_resource_length) ||
434 (resource_length < (minimum_resource_length - 1))) {
435 return (AE_AML_BAD_RESOURCE_LENGTH);
436 }
437 break;
439 default:
441 /* Shouldn't happen (because of validation earlier), but be sure */
443 return (AE_AML_INVALID_RESOURCE_TYPE);
444 }
446 /* Optionally return the resource table index */
448 if (return_index) {
449 *return_index = resource_index;
450 }
452 return (AE_OK);
453 }
455 /*******************************************************************************
456 *
457 * FUNCTION: acpi_ut_get_resource_type
458 *
459 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
460 *
461 * RETURN: The Resource Type with no extraneous bits (except the
462 * Large/Small descriptor bit -- this is left alone)
463 *
464 * DESCRIPTION: Extract the Resource Type/Name from the first byte of
465 * a resource descriptor.
466 *
467 ******************************************************************************/
469 u8 acpi_ut_get_resource_type(void *aml)
470 {
471 ACPI_FUNCTION_ENTRY();
473 /*
474 * Byte 0 contains the descriptor name (Resource Type)
475 * Examine the large/small bit in the resource header
476 */
477 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
479 /* Large Resource Type -- bits 6:0 contain the name */
481 return (ACPI_GET8(aml));
482 } else {
483 /* Small Resource Type -- bits 6:3 contain the name */
485 return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
486 }
487 }
489 /*******************************************************************************
490 *
491 * FUNCTION: acpi_ut_get_resource_length
492 *
493 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
494 *
495 * RETURN: Byte Length
496 *
497 * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
498 * definition, this does not include the size of the descriptor
499 * header or the length field itself.
500 *
501 ******************************************************************************/
503 u16 acpi_ut_get_resource_length(void *aml)
504 {
505 acpi_rs_length resource_length;
507 ACPI_FUNCTION_ENTRY();
509 /*
510 * Byte 0 contains the descriptor name (Resource Type)
511 * Examine the large/small bit in the resource header
512 */
513 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
515 /* Large Resource type -- bytes 1-2 contain the 16-bit length */
517 ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1));
519 } else {
520 /* Small Resource type -- bits 2:0 of byte 0 contain the length */
522 resource_length = (u16) (ACPI_GET8(aml) &
523 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
524 }
526 return (resource_length);
527 }
529 /*******************************************************************************
530 *
531 * FUNCTION: acpi_ut_get_resource_header_length
532 *
533 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
534 *
535 * RETURN: Length of the AML header (depends on large/small descriptor)
536 *
537 * DESCRIPTION: Get the length of the header for this resource.
538 *
539 ******************************************************************************/
541 u8 acpi_ut_get_resource_header_length(void *aml)
542 {
543 ACPI_FUNCTION_ENTRY();
545 /* Examine the large/small bit in the resource header */
547 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
548 return (sizeof(struct aml_resource_large_header));
549 } else {
550 return (sizeof(struct aml_resource_small_header));
551 }
552 }
554 /*******************************************************************************
555 *
556 * FUNCTION: acpi_ut_get_descriptor_length
557 *
558 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
559 *
560 * RETURN: Byte length
561 *
562 * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
563 * length of the descriptor header and the length field itself.
564 * Used to walk descriptor lists.
565 *
566 ******************************************************************************/
568 u32 acpi_ut_get_descriptor_length(void *aml)
569 {
570 ACPI_FUNCTION_ENTRY();
572 /*
573 * Get the Resource Length (does not include header length) and add
574 * the header length (depends on if this is a small or large resource)
575 */
576 return (acpi_ut_get_resource_length(aml) +
577 acpi_ut_get_resource_header_length(aml));
578 }
580 /*******************************************************************************
581 *
582 * FUNCTION: acpi_ut_get_resource_end_tag
583 *
584 * PARAMETERS: obj_desc - The resource template buffer object
585 * end_tag - Where the pointer to the end_tag is returned
586 *
587 * RETURN: Status, pointer to the end tag
588 *
589 * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template
590 * Note: allows a buffer length of zero.
591 *
592 ******************************************************************************/
594 acpi_status
595 acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc,
596 u8 ** end_tag)
597 {
598 acpi_status status;
600 ACPI_FUNCTION_TRACE(ut_get_resource_end_tag);
602 /* Allow a buffer length of zero */
604 if (!obj_desc->buffer.length) {
605 *end_tag = obj_desc->buffer.pointer;
606 return_ACPI_STATUS(AE_OK);
607 }
609 /* Validate the template and get a pointer to the end_tag */
611 status = acpi_ut_walk_aml_resources(obj_desc->buffer.pointer,
612 obj_desc->buffer.length, NULL,
613 (void **)end_tag);
615 return_ACPI_STATUS(status);
616 }