ia64/linux-2.6.18-xen.hg

annotate drivers/acpi/namespace/nsnames.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
rev   line source
ian@0 1 /*******************************************************************************
ian@0 2 *
ian@0 3 * Module Name: nsnames - Name manipulation and search
ian@0 4 *
ian@0 5 ******************************************************************************/
ian@0 6
ian@0 7 /*
ian@0 8 * Copyright (C) 2000 - 2006, R. Byron Moore
ian@0 9 * All rights reserved.
ian@0 10 *
ian@0 11 * Redistribution and use in source and binary forms, with or without
ian@0 12 * modification, are permitted provided that the following conditions
ian@0 13 * are met:
ian@0 14 * 1. Redistributions of source code must retain the above copyright
ian@0 15 * notice, this list of conditions, and the following disclaimer,
ian@0 16 * without modification.
ian@0 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
ian@0 18 * substantially similar to the "NO WARRANTY" disclaimer below
ian@0 19 * ("Disclaimer") and any redistribution must be conditioned upon
ian@0 20 * including a substantially similar Disclaimer requirement for further
ian@0 21 * binary redistribution.
ian@0 22 * 3. Neither the names of the above-listed copyright holders nor the names
ian@0 23 * of any contributors may be used to endorse or promote products derived
ian@0 24 * from this software without specific prior written permission.
ian@0 25 *
ian@0 26 * Alternatively, this software may be distributed under the terms of the
ian@0 27 * GNU General Public License ("GPL") version 2 as published by the Free
ian@0 28 * Software Foundation.
ian@0 29 *
ian@0 30 * NO WARRANTY
ian@0 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
ian@0 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
ian@0 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
ian@0 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
ian@0 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ian@0 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ian@0 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ian@0 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
ian@0 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
ian@0 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
ian@0 41 * POSSIBILITY OF SUCH DAMAGES.
ian@0 42 */
ian@0 43
ian@0 44 #include <acpi/acpi.h>
ian@0 45 #include <acpi/amlcode.h>
ian@0 46 #include <acpi/acnamesp.h>
ian@0 47
ian@0 48 #define _COMPONENT ACPI_NAMESPACE
ian@0 49 ACPI_MODULE_NAME("nsnames")
ian@0 50
ian@0 51 /*******************************************************************************
ian@0 52 *
ian@0 53 * FUNCTION: acpi_ns_build_external_path
ian@0 54 *
ian@0 55 * PARAMETERS: Node - NS node whose pathname is needed
ian@0 56 * Size - Size of the pathname
ian@0 57 * *name_buffer - Where to return the pathname
ian@0 58 *
ian@0 59 * RETURN: Places the pathname into the name_buffer, in external format
ian@0 60 * (name segments separated by path separators)
ian@0 61 *
ian@0 62 * DESCRIPTION: Generate a full pathaname
ian@0 63 *
ian@0 64 ******************************************************************************/
ian@0 65 void
ian@0 66 acpi_ns_build_external_path(struct acpi_namespace_node *node,
ian@0 67 acpi_size size, char *name_buffer)
ian@0 68 {
ian@0 69 acpi_size index;
ian@0 70 struct acpi_namespace_node *parent_node;
ian@0 71
ian@0 72 ACPI_FUNCTION_ENTRY();
ian@0 73
ian@0 74 /* Special case for root */
ian@0 75
ian@0 76 index = size - 1;
ian@0 77 if (index < ACPI_NAME_SIZE) {
ian@0 78 name_buffer[0] = AML_ROOT_PREFIX;
ian@0 79 name_buffer[1] = 0;
ian@0 80 return;
ian@0 81 }
ian@0 82
ian@0 83 /* Store terminator byte, then build name backwards */
ian@0 84
ian@0 85 parent_node = node;
ian@0 86 name_buffer[index] = 0;
ian@0 87
ian@0 88 while ((index > ACPI_NAME_SIZE) && (parent_node != acpi_gbl_root_node)) {
ian@0 89 index -= ACPI_NAME_SIZE;
ian@0 90
ian@0 91 /* Put the name into the buffer */
ian@0 92
ian@0 93 ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name);
ian@0 94 parent_node = acpi_ns_get_parent_node(parent_node);
ian@0 95
ian@0 96 /* Prefix name with the path separator */
ian@0 97
ian@0 98 index--;
ian@0 99 name_buffer[index] = ACPI_PATH_SEPARATOR;
ian@0 100 }
ian@0 101
ian@0 102 /* Overwrite final separator with the root prefix character */
ian@0 103
ian@0 104 name_buffer[index] = AML_ROOT_PREFIX;
ian@0 105
ian@0 106 if (index != 0) {
ian@0 107 ACPI_ERROR((AE_INFO,
ian@0 108 "Could not construct pathname; index=%X, size=%X, Path=%s",
ian@0 109 (u32) index, (u32) size, &name_buffer[size]));
ian@0 110 }
ian@0 111
ian@0 112 return;
ian@0 113 }
ian@0 114
ian@0 115 #ifdef ACPI_DEBUG_OUTPUT
ian@0 116 /*******************************************************************************
ian@0 117 *
ian@0 118 * FUNCTION: acpi_ns_get_external_pathname
ian@0 119 *
ian@0 120 * PARAMETERS: Node - Namespace node whose pathname is needed
ian@0 121 *
ian@0 122 * RETURN: Pointer to storage containing the fully qualified name of
ian@0 123 * the node, In external format (name segments separated by path
ian@0 124 * separators.)
ian@0 125 *
ian@0 126 * DESCRIPTION: Used for debug printing in acpi_ns_search_table().
ian@0 127 *
ian@0 128 ******************************************************************************/
ian@0 129
ian@0 130 char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
ian@0 131 {
ian@0 132 char *name_buffer;
ian@0 133 acpi_size size;
ian@0 134
ian@0 135 ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node);
ian@0 136
ian@0 137 /* Calculate required buffer size based on depth below root */
ian@0 138
ian@0 139 size = acpi_ns_get_pathname_length(node);
ian@0 140
ian@0 141 /* Allocate a buffer to be returned to caller */
ian@0 142
ian@0 143 name_buffer = ACPI_ALLOCATE_ZEROED(size);
ian@0 144 if (!name_buffer) {
ian@0 145 ACPI_ERROR((AE_INFO, "Allocation failure"));
ian@0 146 return_PTR(NULL);
ian@0 147 }
ian@0 148
ian@0 149 /* Build the path in the allocated buffer */
ian@0 150
ian@0 151 acpi_ns_build_external_path(node, size, name_buffer);
ian@0 152 return_PTR(name_buffer);
ian@0 153 }
ian@0 154 #endif
ian@0 155
ian@0 156 /*******************************************************************************
ian@0 157 *
ian@0 158 * FUNCTION: acpi_ns_get_pathname_length
ian@0 159 *
ian@0 160 * PARAMETERS: Node - Namespace node
ian@0 161 *
ian@0 162 * RETURN: Length of path, including prefix
ian@0 163 *
ian@0 164 * DESCRIPTION: Get the length of the pathname string for this node
ian@0 165 *
ian@0 166 ******************************************************************************/
ian@0 167
ian@0 168 acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
ian@0 169 {
ian@0 170 acpi_size size;
ian@0 171 struct acpi_namespace_node *next_node;
ian@0 172
ian@0 173 ACPI_FUNCTION_ENTRY();
ian@0 174
ian@0 175 /*
ian@0 176 * Compute length of pathname as 5 * number of name segments.
ian@0 177 * Go back up the parent tree to the root
ian@0 178 */
ian@0 179 size = 0;
ian@0 180 next_node = node;
ian@0 181
ian@0 182 while (next_node && (next_node != acpi_gbl_root_node)) {
ian@0 183 size += ACPI_PATH_SEGMENT_LENGTH;
ian@0 184 next_node = acpi_ns_get_parent_node(next_node);
ian@0 185 }
ian@0 186
ian@0 187 if (!size) {
ian@0 188 size = 1; /* Root node case */
ian@0 189 }
ian@0 190
ian@0 191 return (size + 1); /* +1 for null string terminator */
ian@0 192 }
ian@0 193
ian@0 194 /*******************************************************************************
ian@0 195 *
ian@0 196 * FUNCTION: acpi_ns_handle_to_pathname
ian@0 197 *
ian@0 198 * PARAMETERS: target_handle - Handle of named object whose name is
ian@0 199 * to be found
ian@0 200 * Buffer - Where the pathname is returned
ian@0 201 *
ian@0 202 * RETURN: Status, Buffer is filled with pathname if status is AE_OK
ian@0 203 *
ian@0 204 * DESCRIPTION: Build and return a full namespace pathname
ian@0 205 *
ian@0 206 ******************************************************************************/
ian@0 207
ian@0 208 acpi_status
ian@0 209 acpi_ns_handle_to_pathname(acpi_handle target_handle,
ian@0 210 struct acpi_buffer * buffer)
ian@0 211 {
ian@0 212 acpi_status status;
ian@0 213 struct acpi_namespace_node *node;
ian@0 214 acpi_size required_size;
ian@0 215
ian@0 216 ACPI_FUNCTION_TRACE_PTR(ns_handle_to_pathname, target_handle);
ian@0 217
ian@0 218 node = acpi_ns_map_handle_to_node(target_handle);
ian@0 219 if (!node) {
ian@0 220 return_ACPI_STATUS(AE_BAD_PARAMETER);
ian@0 221 }
ian@0 222
ian@0 223 /* Determine size required for the caller buffer */
ian@0 224
ian@0 225 required_size = acpi_ns_get_pathname_length(node);
ian@0 226
ian@0 227 /* Validate/Allocate/Clear caller buffer */
ian@0 228
ian@0 229 status = acpi_ut_initialize_buffer(buffer, required_size);
ian@0 230 if (ACPI_FAILURE(status)) {
ian@0 231 return_ACPI_STATUS(status);
ian@0 232 }
ian@0 233
ian@0 234 /* Build the path in the caller buffer */
ian@0 235
ian@0 236 acpi_ns_build_external_path(node, required_size, buffer->pointer);
ian@0 237
ian@0 238 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n",
ian@0 239 (char *)buffer->pointer, (u32) required_size));
ian@0 240 return_ACPI_STATUS(AE_OK);
ian@0 241 }