ia64/linux-2.6.18-xen.hg

view drivers/acpi/namespace/nssearch.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: nssearch - Namespace search
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>
47 #define _COMPONENT ACPI_NAMESPACE
48 ACPI_MODULE_NAME("nssearch")
50 /* Local prototypes */
51 static acpi_status
52 acpi_ns_search_parent_tree(u32 target_name,
53 struct acpi_namespace_node *node,
54 acpi_object_type type,
55 struct acpi_namespace_node **return_node);
57 /*******************************************************************************
58 *
59 * FUNCTION: acpi_ns_search_one_scope
60 *
61 * PARAMETERS: target_name - Ascii ACPI name to search for
62 * parent_node - Starting node where search will begin
63 * Type - Object type to match
64 * return_node - Where the matched Named obj is returned
65 *
66 * RETURN: Status
67 *
68 * DESCRIPTION: Search a single level of the namespace. Performs a
69 * simple search of the specified level, and does not add
70 * entries or search parents.
71 *
72 *
73 * Named object lists are built (and subsequently dumped) in the
74 * order in which the names are encountered during the namespace load;
75 *
76 * All namespace searching is linear in this implementation, but
77 * could be easily modified to support any improved search
78 * algorithm. However, the linear search was chosen for simplicity
79 * and because the trees are small and the other interpreter
80 * execution overhead is relatively high.
81 *
82 * Note: CPU execution analysis has shown that the AML interpreter spends
83 * a very small percentage of its time searching the namespace. Therefore,
84 * the linear search seems to be sufficient, as there would seem to be
85 * little value in improving the search.
86 *
87 ******************************************************************************/
89 acpi_status
90 acpi_ns_search_one_scope(u32 target_name,
91 struct acpi_namespace_node *parent_node,
92 acpi_object_type type,
93 struct acpi_namespace_node **return_node)
94 {
95 struct acpi_namespace_node *node;
97 ACPI_FUNCTION_TRACE(ns_search_one_scope);
99 #ifdef ACPI_DEBUG_OUTPUT
100 if (ACPI_LV_NAMES & acpi_dbg_level) {
101 char *scope_name;
103 scope_name = acpi_ns_get_external_pathname(parent_node);
104 if (scope_name) {
105 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
106 "Searching %s (%p) For [%4.4s] (%s)\n",
107 scope_name, parent_node,
108 ACPI_CAST_PTR(char, &target_name),
109 acpi_ut_get_type_name(type)));
111 ACPI_FREE(scope_name);
112 }
113 }
114 #endif
116 /*
117 * Search for name at this namespace level, which is to say that we
118 * must search for the name among the children of this object
119 */
120 node = parent_node->child;
121 while (node) {
123 /* Check for match against the name */
125 if (node->name.integer == target_name) {
127 /* Resolve a control method alias if any */
129 if (acpi_ns_get_type(node) ==
130 ACPI_TYPE_LOCAL_METHOD_ALIAS) {
131 node =
132 ACPI_CAST_PTR(struct acpi_namespace_node,
133 node->object);
134 }
136 /* Found matching entry */
138 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
139 "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
140 ACPI_CAST_PTR(char, &target_name),
141 acpi_ut_get_type_name(node->type),
142 node,
143 acpi_ut_get_node_name(parent_node),
144 parent_node));
146 *return_node = node;
147 return_ACPI_STATUS(AE_OK);
148 }
150 /*
151 * The last entry in the list points back to the parent,
152 * so a flag is used to indicate the end-of-list
153 */
154 if (node->flags & ANOBJ_END_OF_PEER_LIST) {
156 /* Searched entire list, we are done */
158 break;
159 }
161 /* Didn't match name, move on to the next peer object */
163 node = node->peer;
164 }
166 /* Searched entire namespace level, not found */
168 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
169 "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
170 ACPI_CAST_PTR(char, &target_name),
171 acpi_ut_get_type_name(type),
172 acpi_ut_get_node_name(parent_node), parent_node,
173 parent_node->child));
175 return_ACPI_STATUS(AE_NOT_FOUND);
176 }
178 /*******************************************************************************
179 *
180 * FUNCTION: acpi_ns_search_parent_tree
181 *
182 * PARAMETERS: target_name - Ascii ACPI name to search for
183 * Node - Starting node where search will begin
184 * Type - Object type to match
185 * return_node - Where the matched Node is returned
186 *
187 * RETURN: Status
188 *
189 * DESCRIPTION: Called when a name has not been found in the current namespace
190 * level. Before adding it or giving up, ACPI scope rules require
191 * searching enclosing scopes in cases identified by acpi_ns_local().
192 *
193 * "A name is located by finding the matching name in the current
194 * name space, and then in the parent name space. If the parent
195 * name space does not contain the name, the search continues
196 * recursively until either the name is found or the name space
197 * does not have a parent (the root of the name space). This
198 * indicates that the name is not found" (From ACPI Specification,
199 * section 5.3)
200 *
201 ******************************************************************************/
203 static acpi_status
204 acpi_ns_search_parent_tree(u32 target_name,
205 struct acpi_namespace_node *node,
206 acpi_object_type type,
207 struct acpi_namespace_node **return_node)
208 {
209 acpi_status status;
210 struct acpi_namespace_node *parent_node;
212 ACPI_FUNCTION_TRACE(ns_search_parent_tree);
214 parent_node = acpi_ns_get_parent_node(node);
216 /*
217 * If there is no parent (i.e., we are at the root) or type is "local",
218 * we won't be searching the parent tree.
219 */
220 if (!parent_node) {
221 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
222 ACPI_CAST_PTR(char, &target_name)));
223 return_ACPI_STATUS(AE_NOT_FOUND);
224 }
226 if (acpi_ns_local(type)) {
227 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
228 "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
229 ACPI_CAST_PTR(char, &target_name),
230 acpi_ut_get_type_name(type)));
231 return_ACPI_STATUS(AE_NOT_FOUND);
232 }
234 /* Search the parent tree */
236 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
237 "Searching parent [%4.4s] for [%4.4s]\n",
238 acpi_ut_get_node_name(parent_node),
239 ACPI_CAST_PTR(char, &target_name)));
241 /*
242 * Search parents until target is found or we have backed up to the root
243 */
244 while (parent_node) {
245 /*
246 * Search parent scope. Use TYPE_ANY because we don't care about the
247 * object type at this point, we only care about the existence of
248 * the actual name we are searching for. Typechecking comes later.
249 */
250 status =
251 acpi_ns_search_one_scope(target_name, parent_node,
252 ACPI_TYPE_ANY, return_node);
253 if (ACPI_SUCCESS(status)) {
254 return_ACPI_STATUS(status);
255 }
257 /* Not found here, go up another level (until we reach the root) */
259 parent_node = acpi_ns_get_parent_node(parent_node);
260 }
262 /* Not found in parent tree */
264 return_ACPI_STATUS(AE_NOT_FOUND);
265 }
267 /*******************************************************************************
268 *
269 * FUNCTION: acpi_ns_search_and_enter
270 *
271 * PARAMETERS: target_name - Ascii ACPI name to search for (4 chars)
272 * walk_state - Current state of the walk
273 * Node - Starting node where search will begin
274 * interpreter_mode - Add names only in ACPI_MODE_LOAD_PASS_x.
275 * Otherwise,search only.
276 * Type - Object type to match
277 * Flags - Flags describing the search restrictions
278 * return_node - Where the Node is returned
279 *
280 * RETURN: Status
281 *
282 * DESCRIPTION: Search for a name segment in a single namespace level,
283 * optionally adding it if it is not found. If the passed
284 * Type is not Any and the type previously stored in the
285 * entry was Any (i.e. unknown), update the stored type.
286 *
287 * In ACPI_IMODE_EXECUTE, search only.
288 * In other modes, search and add if not found.
289 *
290 ******************************************************************************/
292 acpi_status
293 acpi_ns_search_and_enter(u32 target_name,
294 struct acpi_walk_state *walk_state,
295 struct acpi_namespace_node *node,
296 acpi_interpreter_mode interpreter_mode,
297 acpi_object_type type,
298 u32 flags, struct acpi_namespace_node **return_node)
299 {
300 acpi_status status;
301 struct acpi_namespace_node *new_node;
303 ACPI_FUNCTION_TRACE(ns_search_and_enter);
305 /* Parameter validation */
307 if (!node || !target_name || !return_node) {
308 ACPI_ERROR((AE_INFO,
309 "Null parameter: Node %p Name %X ReturnNode %p",
310 node, target_name, return_node));
311 return_ACPI_STATUS(AE_BAD_PARAMETER);
312 }
314 /*
315 * Name must consist of valid ACPI characters. We will repair the name if
316 * necessary because we don't want to abort because of this, but we want
317 * all namespace names to be printable. A warning message is appropriate.
318 *
319 * This issue came up because there are in fact machines that exhibit
320 * this problem, and we want to be able to enable ACPI support for them,
321 * even though there are a few bad names.
322 */
323 if (!acpi_ut_valid_acpi_name(target_name)) {
324 target_name = acpi_ut_repair_name(target_name);
326 /* Report warning only if in strict mode or debug mode */
328 if (!acpi_gbl_enable_interpreter_slack) {
329 ACPI_WARNING((AE_INFO,
330 "Found bad character(s) in name, repaired: [%4.4s]\n",
331 ACPI_CAST_PTR(char, &target_name)));
332 } else {
333 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
334 "Found bad character(s) in name, repaired: [%4.4s]\n",
335 ACPI_CAST_PTR(char, &target_name)));
336 }
337 }
339 /* Try to find the name in the namespace level specified by the caller */
341 *return_node = ACPI_ENTRY_NOT_FOUND;
342 status = acpi_ns_search_one_scope(target_name, node, type, return_node);
343 if (status != AE_NOT_FOUND) {
344 /*
345 * If we found it AND the request specifies that a find is an error,
346 * return the error
347 */
348 if ((status == AE_OK) && (flags & ACPI_NS_ERROR_IF_FOUND)) {
349 status = AE_ALREADY_EXISTS;
350 }
352 /* Either found it or there was an error: finished either way */
354 return_ACPI_STATUS(status);
355 }
357 /*
358 * The name was not found. If we are NOT performing the first pass
359 * (name entry) of loading the namespace, search the parent tree (all the
360 * way to the root if necessary.) We don't want to perform the parent
361 * search when the namespace is actually being loaded. We want to perform
362 * the search when namespace references are being resolved (load pass 2)
363 * and during the execution phase.
364 */
365 if ((interpreter_mode != ACPI_IMODE_LOAD_PASS1) &&
366 (flags & ACPI_NS_SEARCH_PARENT)) {
367 /*
368 * Not found at this level - search parent tree according to the
369 * ACPI specification
370 */
371 status =
372 acpi_ns_search_parent_tree(target_name, node, type,
373 return_node);
374 if (ACPI_SUCCESS(status)) {
375 return_ACPI_STATUS(status);
376 }
377 }
379 /* In execute mode, just search, never add names. Exit now */
381 if (interpreter_mode == ACPI_IMODE_EXECUTE) {
382 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
383 "%4.4s Not found in %p [Not adding]\n",
384 ACPI_CAST_PTR(char, &target_name), node));
386 return_ACPI_STATUS(AE_NOT_FOUND);
387 }
389 /* Create the new named object */
391 new_node = acpi_ns_create_node(target_name);
392 if (!new_node) {
393 return_ACPI_STATUS(AE_NO_MEMORY);
394 }
395 #ifdef ACPI_ASL_COMPILER
396 /*
397 * Node is an object defined by an External() statement
398 */
399 if (flags & ACPI_NS_EXTERNAL) {
400 new_node->flags |= ANOBJ_IS_EXTERNAL;
401 }
402 #endif
404 /* Install the new object into the parent's list of children */
406 acpi_ns_install_node(walk_state, node, new_node, type);
407 *return_node = new_node;
408 return_ACPI_STATUS(AE_OK);
409 }