ia64/linux-2.6.18-xen.hg

view drivers/acpi/events/evevent.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: evevent - Fixed Event handling and dispatch
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/acevents.h>
47 #define _COMPONENT ACPI_EVENTS
48 ACPI_MODULE_NAME("evevent")
50 /* Local prototypes */
51 static acpi_status acpi_ev_fixed_event_initialize(void);
53 static u32 acpi_ev_fixed_event_dispatch(u32 event);
55 /*******************************************************************************
56 *
57 * FUNCTION: acpi_ev_initialize_events
58 *
59 * PARAMETERS: None
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE)
64 *
65 ******************************************************************************/
67 acpi_status acpi_ev_initialize_events(void)
68 {
69 acpi_status status;
71 ACPI_FUNCTION_TRACE(ev_initialize_events);
73 /* Make sure we have ACPI tables */
75 if (!acpi_gbl_DSDT) {
76 ACPI_WARNING((AE_INFO, "No ACPI tables present!"));
77 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
78 }
80 /*
81 * Initialize the Fixed and General Purpose Events. This is done prior to
82 * enabling SCIs to prevent interrupts from occurring before the handlers are
83 * installed.
84 */
85 status = acpi_ev_fixed_event_initialize();
86 if (ACPI_FAILURE(status)) {
87 ACPI_EXCEPTION((AE_INFO, status,
88 "Unable to initialize fixed events"));
89 return_ACPI_STATUS(status);
90 }
92 status = acpi_ev_gpe_initialize();
93 if (ACPI_FAILURE(status)) {
94 ACPI_EXCEPTION((AE_INFO, status,
95 "Unable to initialize general purpose events"));
96 return_ACPI_STATUS(status);
97 }
99 return_ACPI_STATUS(status);
100 }
102 /*******************************************************************************
103 *
104 * FUNCTION: acpi_ev_install_fadt_gpes
105 *
106 * PARAMETERS: None
107 *
108 * RETURN: Status
109 *
110 * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks
111 * (0 and 1). This causes the _PRW methods to be run, so the HW
112 * must be fully initialized at this point, including global lock
113 * support.
114 *
115 ******************************************************************************/
117 acpi_status acpi_ev_install_fadt_gpes(void)
118 {
119 acpi_status status;
121 ACPI_FUNCTION_TRACE(ev_install_fadt_gpes);
123 /* Namespace must be locked */
125 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
126 if (ACPI_FAILURE(status)) {
127 return (status);
128 }
130 /* FADT GPE Block 0 */
132 (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
133 acpi_gbl_gpe_fadt_blocks[0]);
135 /* FADT GPE Block 1 */
137 (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
138 acpi_gbl_gpe_fadt_blocks[1]);
140 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
141 return_ACPI_STATUS(AE_OK);
142 }
144 /*******************************************************************************
145 *
146 * FUNCTION: acpi_ev_install_xrupt_handlers
147 *
148 * PARAMETERS: None
149 *
150 * RETURN: Status
151 *
152 * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
153 *
154 ******************************************************************************/
156 acpi_status acpi_ev_install_xrupt_handlers(void)
157 {
158 acpi_status status;
160 ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers);
162 /* Install the SCI handler */
164 status = acpi_ev_install_sci_handler();
165 if (ACPI_FAILURE(status)) {
166 ACPI_EXCEPTION((AE_INFO, status,
167 "Unable to install System Control Interrupt handler"));
168 return_ACPI_STATUS(status);
169 }
171 /* Install the handler for the Global Lock */
173 status = acpi_ev_init_global_lock_handler();
174 if (ACPI_FAILURE(status)) {
175 ACPI_EXCEPTION((AE_INFO, status,
176 "Unable to initialize Global Lock handler"));
177 return_ACPI_STATUS(status);
178 }
180 acpi_gbl_events_initialized = TRUE;
181 return_ACPI_STATUS(status);
182 }
184 /*******************************************************************************
185 *
186 * FUNCTION: acpi_ev_fixed_event_initialize
187 *
188 * PARAMETERS: None
189 *
190 * RETURN: Status
191 *
192 * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
193 *
194 ******************************************************************************/
196 static acpi_status acpi_ev_fixed_event_initialize(void)
197 {
198 acpi_native_uint i;
199 acpi_status status;
201 /*
202 * Initialize the structure that keeps track of fixed event handlers
203 * and enable the fixed events.
204 */
205 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
206 acpi_gbl_fixed_event_handlers[i].handler = NULL;
207 acpi_gbl_fixed_event_handlers[i].context = NULL;
209 /* Enable the fixed event */
211 if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
212 status =
213 acpi_set_register(acpi_gbl_fixed_event_info[i].
214 enable_register_id, 0,
215 ACPI_MTX_LOCK);
216 if (ACPI_FAILURE(status)) {
217 return (status);
218 }
219 }
220 }
222 return (AE_OK);
223 }
225 /*******************************************************************************
226 *
227 * FUNCTION: acpi_ev_fixed_event_detect
228 *
229 * PARAMETERS: None
230 *
231 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
232 *
233 * DESCRIPTION: Checks the PM status register for active fixed events
234 *
235 ******************************************************************************/
237 u32 acpi_ev_fixed_event_detect(void)
238 {
239 u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
240 u32 fixed_status;
241 u32 fixed_enable;
242 acpi_native_uint i;
244 ACPI_FUNCTION_NAME(ev_fixed_event_detect);
246 /*
247 * Read the fixed feature status and enable registers, as all the cases
248 * depend on their values. Ignore errors here.
249 */
250 (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
251 ACPI_REGISTER_PM1_STATUS, &fixed_status);
252 (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
253 ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
255 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
256 "Fixed Event Block: Enable %08X Status %08X\n",
257 fixed_enable, fixed_status));
259 /*
260 * Check for all possible Fixed Events and dispatch those that are active
261 */
262 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
264 /* Both the status and enable bits must be on for this event */
266 if ((fixed_status & acpi_gbl_fixed_event_info[i].
267 status_bit_mask)
268 && (fixed_enable & acpi_gbl_fixed_event_info[i].
269 enable_bit_mask)) {
271 /* Found an active (signalled) event */
273 int_status |= acpi_ev_fixed_event_dispatch((u32) i);
274 }
275 }
277 return (int_status);
278 }
280 /*******************************************************************************
281 *
282 * FUNCTION: acpi_ev_fixed_event_dispatch
283 *
284 * PARAMETERS: Event - Event type
285 *
286 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
287 *
288 * DESCRIPTION: Clears the status bit for the requested event, calls the
289 * handler that previously registered for the event.
290 *
291 ******************************************************************************/
293 static u32 acpi_ev_fixed_event_dispatch(u32 event)
294 {
296 ACPI_FUNCTION_ENTRY();
298 /* Clear the status bit */
300 (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
301 status_register_id, 1, ACPI_MTX_DO_NOT_LOCK);
303 /*
304 * Make sure we've got a handler. If not, report an error.
305 * The event is disabled to prevent further interrupts.
306 */
307 if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
308 (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
309 enable_register_id, 0,
310 ACPI_MTX_DO_NOT_LOCK);
312 ACPI_ERROR((AE_INFO,
313 "No installed handler for fixed event [%08X]",
314 event));
316 return (ACPI_INTERRUPT_NOT_HANDLED);
317 }
319 /* Invoke the Fixed Event handler */
321 return ((acpi_gbl_fixed_event_handlers[event].
322 handler) (acpi_gbl_fixed_event_handlers[event].context));
323 }