ia64/linux-2.6.18-xen.hg

view drivers/acpi/events/evxfregn.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: evxfregn - External Interfaces, ACPI Operation Regions and
4 * Address Spaces.
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>
47 #include <acpi/acevents.h>
49 #define _COMPONENT ACPI_EVENTS
50 ACPI_MODULE_NAME("evxfregn")
52 /*******************************************************************************
53 *
54 * FUNCTION: acpi_install_address_space_handler
55 *
56 * PARAMETERS: Device - Handle for the device
57 * space_id - The address space ID
58 * Handler - Address of the handler
59 * Setup - Address of the setup function
60 * Context - Value passed to the handler on each access
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Install a handler for all op_regions of a given space_id.
65 *
66 ******************************************************************************/
67 acpi_status
68 acpi_install_address_space_handler(acpi_handle device,
69 acpi_adr_space_type space_id,
70 acpi_adr_space_handler handler,
71 acpi_adr_space_setup setup, void *context)
72 {
73 struct acpi_namespace_node *node;
74 acpi_status status;
76 ACPI_FUNCTION_TRACE(acpi_install_address_space_handler);
78 /* Parameter validation */
80 if (!device) {
81 return_ACPI_STATUS(AE_BAD_PARAMETER);
82 }
84 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
85 if (ACPI_FAILURE(status)) {
86 return_ACPI_STATUS(status);
87 }
89 /* Convert and validate the device handle */
91 node = acpi_ns_map_handle_to_node(device);
92 if (!node) {
93 status = AE_BAD_PARAMETER;
94 goto unlock_and_exit;
95 }
97 /* Install the handler for all Regions for this Space ID */
99 status =
100 acpi_ev_install_space_handler(node, space_id, handler, setup,
101 context);
102 if (ACPI_FAILURE(status)) {
103 goto unlock_and_exit;
104 }
106 /* Run all _REG methods for this address space */
108 status = acpi_ev_execute_reg_methods(node, space_id);
110 unlock_and_exit:
111 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
112 return_ACPI_STATUS(status);
113 }
115 ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler)
117 /*******************************************************************************
118 *
119 * FUNCTION: acpi_remove_address_space_handler
120 *
121 * PARAMETERS: Device - Handle for the device
122 * space_id - The address space ID
123 * Handler - Address of the handler
124 *
125 * RETURN: Status
126 *
127 * DESCRIPTION: Remove a previously installed handler.
128 *
129 ******************************************************************************/
130 acpi_status
131 acpi_remove_address_space_handler(acpi_handle device,
132 acpi_adr_space_type space_id,
133 acpi_adr_space_handler handler)
134 {
135 union acpi_operand_object *obj_desc;
136 union acpi_operand_object *handler_obj;
137 union acpi_operand_object *region_obj;
138 union acpi_operand_object **last_obj_ptr;
139 struct acpi_namespace_node *node;
140 acpi_status status;
142 ACPI_FUNCTION_TRACE(acpi_remove_address_space_handler);
144 /* Parameter validation */
146 if (!device) {
147 return_ACPI_STATUS(AE_BAD_PARAMETER);
148 }
150 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
151 if (ACPI_FAILURE(status)) {
152 return_ACPI_STATUS(status);
153 }
155 /* Convert and validate the device handle */
157 node = acpi_ns_map_handle_to_node(device);
158 if (!node ||
159 ((node->type != ACPI_TYPE_DEVICE) &&
160 (node->type != ACPI_TYPE_PROCESSOR) &&
161 (node->type != ACPI_TYPE_THERMAL) &&
162 (node != acpi_gbl_root_node))) {
163 status = AE_BAD_PARAMETER;
164 goto unlock_and_exit;
165 }
167 /* Make sure the internal object exists */
169 obj_desc = acpi_ns_get_attached_object(node);
170 if (!obj_desc) {
171 status = AE_NOT_EXIST;
172 goto unlock_and_exit;
173 }
175 /* Find the address handler the user requested */
177 handler_obj = obj_desc->device.handler;
178 last_obj_ptr = &obj_desc->device.handler;
179 while (handler_obj) {
181 /* We have a handler, see if user requested this one */
183 if (handler_obj->address_space.space_id == space_id) {
185 /* Handler must be the same as the installed handler */
187 if (handler_obj->address_space.handler != handler) {
188 status = AE_BAD_PARAMETER;
189 goto unlock_and_exit;
190 }
192 /* Matched space_id, first dereference this in the Regions */
194 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
195 "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
196 handler_obj, handler,
197 acpi_ut_get_region_name(space_id),
198 node, obj_desc));
200 region_obj = handler_obj->address_space.region_list;
202 /* Walk the handler's region list */
204 while (region_obj) {
205 /*
206 * First disassociate the handler from the region.
207 *
208 * NOTE: this doesn't mean that the region goes away
209 * The region is just inaccessible as indicated to
210 * the _REG method
211 */
212 acpi_ev_detach_region(region_obj, TRUE);
214 /*
215 * Walk the list: Just grab the head because the
216 * detach_region removed the previous head.
217 */
218 region_obj =
219 handler_obj->address_space.region_list;
221 }
223 /* Remove this Handler object from the list */
225 *last_obj_ptr = handler_obj->address_space.next;
227 /* Now we can delete the handler object */
229 acpi_ut_remove_reference(handler_obj);
230 goto unlock_and_exit;
231 }
233 /* Walk the linked list of handlers */
235 last_obj_ptr = &handler_obj->address_space.next;
236 handler_obj = handler_obj->address_space.next;
237 }
239 /* The handler does not exist */
241 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
242 "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n",
243 handler, acpi_ut_get_region_name(space_id), space_id,
244 node, obj_desc));
246 status = AE_NOT_EXIST;
248 unlock_and_exit:
249 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
250 return_ACPI_STATUS(status);
251 }
253 ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)