ia64/linux-2.6.18-xen.hg

view drivers/acpi/namespace/nsload.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: nsload - namespace loading/expanding/contracting procedures
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/acnamesp.h>
46 #include <acpi/acdispat.h>
48 #define _COMPONENT ACPI_NAMESPACE
49 ACPI_MODULE_NAME("nsload")
51 /* Local prototypes */
52 static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type);
54 #ifdef ACPI_FUTURE_IMPLEMENTATION
55 acpi_status acpi_ns_unload_namespace(acpi_handle handle);
57 static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
58 #endif
60 #ifndef ACPI_NO_METHOD_EXECUTION
61 /*******************************************************************************
62 *
63 * FUNCTION: acpi_ns_load_table
64 *
65 * PARAMETERS: table_desc - Descriptor for table to be loaded
66 * Node - Owning NS node
67 *
68 * RETURN: Status
69 *
70 * DESCRIPTION: Load one ACPI table into the namespace
71 *
72 ******************************************************************************/
74 acpi_status
75 acpi_ns_load_table(struct acpi_table_desc *table_desc,
76 struct acpi_namespace_node *node)
77 {
78 acpi_status status;
80 ACPI_FUNCTION_TRACE(ns_load_table);
82 /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */
84 if (!
85 (acpi_gbl_table_data[table_desc->type].
86 flags & ACPI_TABLE_EXECUTABLE)) {
88 /* Just ignore this table */
90 return_ACPI_STATUS(AE_OK);
91 }
93 /* Check validity of the AML start and length */
95 if (!table_desc->aml_start) {
96 ACPI_ERROR((AE_INFO, "Null AML pointer"));
97 return_ACPI_STATUS(AE_BAD_PARAMETER);
98 }
100 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n",
101 table_desc->aml_start));
103 /* Ignore table if there is no AML contained within */
105 if (!table_desc->aml_length) {
106 ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]",
107 table_desc->pointer->signature));
108 return_ACPI_STATUS(AE_OK);
109 }
111 /*
112 * Parse the table and load the namespace with all named
113 * objects found within. Control methods are NOT parsed
114 * at this time. In fact, the control methods cannot be
115 * parsed until the entire namespace is loaded, because
116 * if a control method makes a forward reference (call)
117 * to another control method, we can't continue parsing
118 * because we don't know how many arguments to parse next!
119 */
120 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
121 "**** Loading table into namespace ****\n"));
123 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
124 if (ACPI_FAILURE(status)) {
125 return_ACPI_STATUS(status);
126 }
128 status = acpi_ns_parse_table(table_desc, node->child);
129 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
131 if (ACPI_FAILURE(status)) {
132 return_ACPI_STATUS(status);
133 }
135 /*
136 * Now we can parse the control methods. We always parse
137 * them here for a sanity check, and if configured for
138 * just-in-time parsing, we delete the control method
139 * parse trees.
140 */
141 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
142 "**** Begin Table Method Parsing and Object Initialization ****\n"));
144 status = acpi_ds_initialize_objects(table_desc, node);
146 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
147 "**** Completed Table Method Parsing and Object Initialization ****\n"));
149 return_ACPI_STATUS(status);
150 }
152 /*******************************************************************************
153 *
154 * FUNCTION: acpi_ns_load_table_by_type
155 *
156 * PARAMETERS: table_type - Id of the table type to load
157 *
158 * RETURN: Status
159 *
160 * DESCRIPTION: Load an ACPI table or tables into the namespace. All tables
161 * of the given type are loaded. The mechanism allows this
162 * routine to be called repeatedly.
163 *
164 ******************************************************************************/
166 static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type)
167 {
168 u32 i;
169 acpi_status status;
170 struct acpi_table_desc *table_desc;
172 ACPI_FUNCTION_TRACE(ns_load_table_by_type);
174 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
175 if (ACPI_FAILURE(status)) {
176 return_ACPI_STATUS(status);
177 }
179 /*
180 * Table types supported are:
181 * DSDT (one), SSDT/PSDT (multiple)
182 */
183 switch (table_type) {
184 case ACPI_TABLE_ID_DSDT:
186 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n"));
188 table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next;
190 /* If table already loaded into namespace, just return */
192 if (table_desc->loaded_into_namespace) {
193 goto unlock_and_exit;
194 }
196 /* Now load the single DSDT */
198 status = acpi_ns_load_table(table_desc, acpi_gbl_root_node);
199 if (ACPI_SUCCESS(status)) {
200 table_desc->loaded_into_namespace = TRUE;
201 }
202 break;
204 case ACPI_TABLE_ID_SSDT:
205 case ACPI_TABLE_ID_PSDT:
207 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
208 "Namespace load: %d SSDT or PSDTs\n",
209 acpi_gbl_table_lists[table_type].count));
211 /*
212 * Traverse list of SSDT or PSDT tables
213 */
214 table_desc = acpi_gbl_table_lists[table_type].next;
215 for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) {
216 /*
217 * Only attempt to load table into namespace if it is not
218 * already loaded!
219 */
220 if (!table_desc->loaded_into_namespace) {
221 status =
222 acpi_ns_load_table(table_desc,
223 acpi_gbl_root_node);
224 if (ACPI_FAILURE(status)) {
225 break;
226 }
228 table_desc->loaded_into_namespace = TRUE;
229 }
231 table_desc = table_desc->next;
232 }
233 break;
235 default:
236 status = AE_SUPPORT;
237 break;
238 }
240 unlock_and_exit:
241 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
242 return_ACPI_STATUS(status);
243 }
245 /*******************************************************************************
246 *
247 * FUNCTION: acpi_load_namespace
248 *
249 * PARAMETERS: None
250 *
251 * RETURN: Status
252 *
253 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT.
254 * (DSDT points to either the BIOS or a buffer.)
255 *
256 ******************************************************************************/
258 acpi_status acpi_ns_load_namespace(void)
259 {
260 acpi_status status;
262 ACPI_FUNCTION_TRACE(acpi_load_name_space);
264 /* There must be at least a DSDT installed */
266 if (acpi_gbl_DSDT == NULL) {
267 ACPI_ERROR((AE_INFO, "DSDT is not in memory"));
268 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
269 }
271 /*
272 * Load the namespace. The DSDT is required,
273 * but the SSDT and PSDT tables are optional.
274 */
275 status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT);
276 if (ACPI_FAILURE(status)) {
277 return_ACPI_STATUS(status);
278 }
280 /* Ignore exceptions from these */
282 (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_SSDT);
283 (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_PSDT);
285 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
286 "ACPI Namespace successfully loaded at root %p\n",
287 acpi_gbl_root_node));
289 return_ACPI_STATUS(status);
290 }
292 #ifdef ACPI_FUTURE_IMPLEMENTATION
293 /*******************************************************************************
294 *
295 * FUNCTION: acpi_ns_delete_subtree
296 *
297 * PARAMETERS: start_handle - Handle in namespace where search begins
298 *
299 * RETURNS Status
300 *
301 * DESCRIPTION: Walks the namespace starting at the given handle and deletes
302 * all objects, entries, and scopes in the entire subtree.
303 *
304 * Namespace/Interpreter should be locked or the subsystem should
305 * be in shutdown before this routine is called.
306 *
307 ******************************************************************************/
309 static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle)
310 {
311 acpi_status status;
312 acpi_handle child_handle;
313 acpi_handle parent_handle;
314 acpi_handle next_child_handle;
315 acpi_handle dummy;
316 u32 level;
318 ACPI_FUNCTION_TRACE(ns_delete_subtree);
320 parent_handle = start_handle;
321 child_handle = NULL;
322 level = 1;
324 /*
325 * Traverse the tree of objects until we bubble back up
326 * to where we started.
327 */
328 while (level > 0) {
330 /* Attempt to get the next object in this scope */
332 status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle,
333 child_handle, &next_child_handle);
335 child_handle = next_child_handle;
337 /* Did we get a new object? */
339 if (ACPI_SUCCESS(status)) {
341 /* Check if this object has any children */
343 if (ACPI_SUCCESS
344 (acpi_get_next_object
345 (ACPI_TYPE_ANY, child_handle, NULL, &dummy))) {
346 /*
347 * There is at least one child of this object,
348 * visit the object
349 */
350 level++;
351 parent_handle = child_handle;
352 child_handle = NULL;
353 }
354 } else {
355 /*
356 * No more children in this object, go back up to
357 * the object's parent
358 */
359 level--;
361 /* Delete all children now */
363 acpi_ns_delete_children(child_handle);
365 child_handle = parent_handle;
366 status = acpi_get_parent(parent_handle, &parent_handle);
367 if (ACPI_FAILURE(status)) {
368 return_ACPI_STATUS(status);
369 }
370 }
371 }
373 /* Now delete the starting object, and we are done */
375 acpi_ns_delete_node(child_handle);
377 return_ACPI_STATUS(AE_OK);
378 }
380 /*******************************************************************************
381 *
382 * FUNCTION: acpi_ns_unload_name_space
383 *
384 * PARAMETERS: Handle - Root of namespace subtree to be deleted
385 *
386 * RETURN: Status
387 *
388 * DESCRIPTION: Shrinks the namespace, typically in response to an undocking
389 * event. Deletes an entire subtree starting from (and
390 * including) the given handle.
391 *
392 ******************************************************************************/
394 acpi_status acpi_ns_unload_namespace(acpi_handle handle)
395 {
396 acpi_status status;
398 ACPI_FUNCTION_TRACE(ns_unload_name_space);
400 /* Parameter validation */
402 if (!acpi_gbl_root_node) {
403 return_ACPI_STATUS(AE_NO_NAMESPACE);
404 }
406 if (!handle) {
407 return_ACPI_STATUS(AE_BAD_PARAMETER);
408 }
410 /* This function does the real work */
412 status = acpi_ns_delete_subtree(handle);
414 return_ACPI_STATUS(status);
415 }
416 #endif
417 #endif