ia64/linux-2.6.18-xen.hg

view drivers/acpi/namespace/nsxfname.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: nsxfname - Public interfaces to the ACPI subsystem
4 * ACPI Namespace oriented interfaces
5 *
6 *****************************************************************************/
8 /*
9 * Copyright (C) 2000 - 2006, R. Byron Moore
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
45 #include <acpi/acpi.h>
46 #include <acpi/acnamesp.h>
48 #define _COMPONENT ACPI_NAMESPACE
49 ACPI_MODULE_NAME("nsxfname")
51 /******************************************************************************
52 *
53 * FUNCTION: acpi_get_handle
54 *
55 * PARAMETERS: Parent - Object to search under (search scope).
56 * Pathname - Pointer to an asciiz string containing the
57 * name
58 * ret_handle - Where the return handle is returned
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: This routine will search for a caller specified name in the
63 * name space. The caller can restrict the search region by
64 * specifying a non NULL parent. The parent value is itself a
65 * namespace handle.
66 *
67 ******************************************************************************/
68 acpi_status
69 acpi_get_handle(acpi_handle parent,
70 acpi_string pathname, acpi_handle * ret_handle)
71 {
72 acpi_status status;
73 struct acpi_namespace_node *node = NULL;
74 struct acpi_namespace_node *prefix_node = NULL;
76 ACPI_FUNCTION_ENTRY();
78 /* Parameter Validation */
80 if (!ret_handle || !pathname) {
81 return (AE_BAD_PARAMETER);
82 }
84 /* Convert a parent handle to a prefix node */
86 if (parent) {
87 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
88 if (ACPI_FAILURE(status)) {
89 return (status);
90 }
92 prefix_node = acpi_ns_map_handle_to_node(parent);
93 if (!prefix_node) {
94 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
95 return (AE_BAD_PARAMETER);
96 }
98 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
99 if (ACPI_FAILURE(status)) {
100 return (status);
101 }
102 }
104 /* Special case for root, since we can't search for it */
106 if (ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH) == 0) {
107 *ret_handle =
108 acpi_ns_convert_entry_to_handle(acpi_gbl_root_node);
109 return (AE_OK);
110 }
112 /*
113 * Find the Node and convert to a handle
114 */
115 status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH,
116 &node);
118 *ret_handle = NULL;
119 if (ACPI_SUCCESS(status)) {
120 *ret_handle = acpi_ns_convert_entry_to_handle(node);
121 }
123 return (status);
124 }
126 ACPI_EXPORT_SYMBOL(acpi_get_handle)
128 /******************************************************************************
129 *
130 * FUNCTION: acpi_get_name
131 *
132 * PARAMETERS: Handle - Handle to be converted to a pathname
133 * name_type - Full pathname or single segment
134 * Buffer - Buffer for returned path
135 *
136 * RETURN: Pointer to a string containing the fully qualified Name.
137 *
138 * DESCRIPTION: This routine returns the fully qualified name associated with
139 * the Handle parameter. This and the acpi_pathname_to_handle are
140 * complementary functions.
141 *
142 ******************************************************************************/
143 acpi_status
144 acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer)
145 {
146 acpi_status status;
147 struct acpi_namespace_node *node;
149 /* Parameter validation */
151 if (name_type > ACPI_NAME_TYPE_MAX) {
152 return (AE_BAD_PARAMETER);
153 }
155 status = acpi_ut_validate_buffer(buffer);
156 if (ACPI_FAILURE(status)) {
157 return (status);
158 }
160 if (name_type == ACPI_FULL_PATHNAME) {
162 /* Get the full pathname (From the namespace root) */
164 status = acpi_ns_handle_to_pathname(handle, buffer);
165 return (status);
166 }
168 /*
169 * Wants the single segment ACPI name.
170 * Validate handle and convert to a namespace Node
171 */
172 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
173 if (ACPI_FAILURE(status)) {
174 return (status);
175 }
177 node = acpi_ns_map_handle_to_node(handle);
178 if (!node) {
179 status = AE_BAD_PARAMETER;
180 goto unlock_and_exit;
181 }
183 /* Validate/Allocate/Clear caller buffer */
185 status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH);
186 if (ACPI_FAILURE(status)) {
187 goto unlock_and_exit;
188 }
190 /* Just copy the ACPI name from the Node and zero terminate it */
192 ACPI_STRNCPY(buffer->pointer, acpi_ut_get_node_name(node),
193 ACPI_NAME_SIZE);
194 ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0;
195 status = AE_OK;
197 unlock_and_exit:
199 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
200 return (status);
201 }
203 ACPI_EXPORT_SYMBOL(acpi_get_name)
205 /******************************************************************************
206 *
207 * FUNCTION: acpi_get_object_info
208 *
209 * PARAMETERS: Handle - Object Handle
210 * Buffer - Where the info is returned
211 *
212 * RETURN: Status
213 *
214 * DESCRIPTION: Returns information about an object as gleaned from the
215 * namespace node and possibly by running several standard
216 * control methods (Such as in the case of a device.)
217 *
218 ******************************************************************************/
219 acpi_status
220 acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
221 {
222 acpi_status status;
223 struct acpi_namespace_node *node;
224 struct acpi_device_info *info;
225 struct acpi_device_info *return_info;
226 struct acpi_compatible_id_list *cid_list = NULL;
227 acpi_size size;
229 /* Parameter validation */
231 if (!handle || !buffer) {
232 return (AE_BAD_PARAMETER);
233 }
235 status = acpi_ut_validate_buffer(buffer);
236 if (ACPI_FAILURE(status)) {
237 return (status);
238 }
240 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info));
241 if (!info) {
242 return (AE_NO_MEMORY);
243 }
245 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
246 if (ACPI_FAILURE(status)) {
247 goto cleanup;
248 }
250 node = acpi_ns_map_handle_to_node(handle);
251 if (!node) {
252 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
253 goto cleanup;
254 }
256 /* Init return structure */
258 size = sizeof(struct acpi_device_info);
260 info->type = node->type;
261 info->name = node->name.integer;
262 info->valid = 0;
264 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
265 if (ACPI_FAILURE(status)) {
266 goto cleanup;
267 }
269 /* If not a device, we are all done */
271 if (info->type == ACPI_TYPE_DEVICE) {
272 /*
273 * Get extra info for ACPI Devices objects only:
274 * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
275 *
276 * Note: none of these methods are required, so they may or may
277 * not be present for this device. The Info->Valid bitfield is used
278 * to indicate which methods were found and ran successfully.
279 */
281 /* Execute the Device._HID method */
283 status = acpi_ut_execute_HID(node, &info->hardware_id);
284 if (ACPI_SUCCESS(status)) {
285 info->valid |= ACPI_VALID_HID;
286 }
288 /* Execute the Device._UID method */
290 status = acpi_ut_execute_UID(node, &info->unique_id);
291 if (ACPI_SUCCESS(status)) {
292 info->valid |= ACPI_VALID_UID;
293 }
295 /* Execute the Device._CID method */
297 status = acpi_ut_execute_CID(node, &cid_list);
298 if (ACPI_SUCCESS(status)) {
299 size += cid_list->size;
300 info->valid |= ACPI_VALID_CID;
301 }
303 /* Execute the Device._STA method */
305 status = acpi_ut_execute_STA(node, &info->current_status);
306 if (ACPI_SUCCESS(status)) {
307 info->valid |= ACPI_VALID_STA;
308 }
310 /* Execute the Device._ADR method */
312 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node,
313 &info->address);
314 if (ACPI_SUCCESS(status)) {
315 info->valid |= ACPI_VALID_ADR;
316 }
318 /* Execute the Device._sx_d methods */
320 status = acpi_ut_execute_sxds(node, info->highest_dstates);
321 if (ACPI_SUCCESS(status)) {
322 info->valid |= ACPI_VALID_SXDS;
323 }
324 }
326 /* Validate/Allocate/Clear caller buffer */
328 status = acpi_ut_initialize_buffer(buffer, size);
329 if (ACPI_FAILURE(status)) {
330 goto cleanup;
331 }
333 /* Populate the return buffer */
335 return_info = buffer->pointer;
336 ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info));
338 if (cid_list) {
339 ACPI_MEMCPY(&return_info->compatibility_id, cid_list,
340 cid_list->size);
341 }
343 cleanup:
344 ACPI_FREE(info);
345 if (cid_list) {
346 ACPI_FREE(cid_list);
347 }
348 return (status);
349 }
351 ACPI_EXPORT_SYMBOL(acpi_get_object_info)