ia64/linux-2.6.18-xen.hg

annotate drivers/acpi/utilities/utinit.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
rev   line source
ian@0 1 /******************************************************************************
ian@0 2 *
ian@0 3 * Module Name: utinit - Common ACPI subsystem initialization
ian@0 4 *
ian@0 5 *****************************************************************************/
ian@0 6
ian@0 7 /*
ian@0 8 * Copyright (C) 2000 - 2006, R. Byron Moore
ian@0 9 * All rights reserved.
ian@0 10 *
ian@0 11 * Redistribution and use in source and binary forms, with or without
ian@0 12 * modification, are permitted provided that the following conditions
ian@0 13 * are met:
ian@0 14 * 1. Redistributions of source code must retain the above copyright
ian@0 15 * notice, this list of conditions, and the following disclaimer,
ian@0 16 * without modification.
ian@0 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
ian@0 18 * substantially similar to the "NO WARRANTY" disclaimer below
ian@0 19 * ("Disclaimer") and any redistribution must be conditioned upon
ian@0 20 * including a substantially similar Disclaimer requirement for further
ian@0 21 * binary redistribution.
ian@0 22 * 3. Neither the names of the above-listed copyright holders nor the names
ian@0 23 * of any contributors may be used to endorse or promote products derived
ian@0 24 * from this software without specific prior written permission.
ian@0 25 *
ian@0 26 * Alternatively, this software may be distributed under the terms of the
ian@0 27 * GNU General Public License ("GPL") version 2 as published by the Free
ian@0 28 * Software Foundation.
ian@0 29 *
ian@0 30 * NO WARRANTY
ian@0 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
ian@0 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
ian@0 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
ian@0 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
ian@0 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ian@0 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ian@0 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ian@0 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
ian@0 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
ian@0 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
ian@0 41 * POSSIBILITY OF SUCH DAMAGES.
ian@0 42 */
ian@0 43
ian@0 44 #include <acpi/acpi.h>
ian@0 45 #include <acpi/acnamesp.h>
ian@0 46 #include <acpi/acevents.h>
ian@0 47
ian@0 48 #define _COMPONENT ACPI_UTILITIES
ian@0 49 ACPI_MODULE_NAME("utinit")
ian@0 50
ian@0 51 /* Local prototypes */
ian@0 52 static void
ian@0 53 acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset);
ian@0 54
ian@0 55 static void acpi_ut_terminate(void);
ian@0 56
ian@0 57 /*******************************************************************************
ian@0 58 *
ian@0 59 * FUNCTION: acpi_ut_fadt_register_error
ian@0 60 *
ian@0 61 * PARAMETERS: register_name - Pointer to string identifying register
ian@0 62 * Value - Actual register contents value
ian@0 63 * Offset - Byte offset in the FADT
ian@0 64 *
ian@0 65 * RETURN: AE_BAD_VALUE
ian@0 66 *
ian@0 67 * DESCRIPTION: Display failure message
ian@0 68 *
ian@0 69 ******************************************************************************/
ian@0 70
ian@0 71 static void
ian@0 72 acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset)
ian@0 73 {
ian@0 74
ian@0 75 ACPI_WARNING((AE_INFO,
ian@0 76 "Invalid FADT value %s=%X at offset %X FADT=%p",
ian@0 77 register_name, value, offset, acpi_gbl_FADT));
ian@0 78 }
ian@0 79
ian@0 80 /******************************************************************************
ian@0 81 *
ian@0 82 * FUNCTION: acpi_ut_validate_fadt
ian@0 83 *
ian@0 84 * PARAMETERS: None
ian@0 85 *
ian@0 86 * RETURN: Status
ian@0 87 *
ian@0 88 * DESCRIPTION: Validate various ACPI registers in the FADT
ian@0 89 *
ian@0 90 ******************************************************************************/
ian@0 91
ian@0 92 acpi_status acpi_ut_validate_fadt(void)
ian@0 93 {
ian@0 94
ian@0 95 /*
ian@0 96 * Verify Fixed ACPI Description Table fields,
ian@0 97 * but don't abort on any problems, just display error
ian@0 98 */
ian@0 99 if (acpi_gbl_FADT->pm1_evt_len < 4) {
ian@0 100 acpi_ut_fadt_register_error("PM1_EVT_LEN",
ian@0 101 (u32) acpi_gbl_FADT->pm1_evt_len,
ian@0 102 ACPI_FADT_OFFSET(pm1_evt_len));
ian@0 103 }
ian@0 104
ian@0 105 if (!acpi_gbl_FADT->pm1_cnt_len) {
ian@0 106 acpi_ut_fadt_register_error("PM1_CNT_LEN", 0,
ian@0 107 ACPI_FADT_OFFSET(pm1_cnt_len));
ian@0 108 }
ian@0 109
ian@0 110 if (!acpi_gbl_FADT->xpm1a_evt_blk.address) {
ian@0 111 acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0,
ian@0 112 ACPI_FADT_OFFSET(xpm1a_evt_blk.
ian@0 113 address));
ian@0 114 }
ian@0 115
ian@0 116 if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) {
ian@0 117 acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0,
ian@0 118 ACPI_FADT_OFFSET(xpm1a_cnt_blk.
ian@0 119 address));
ian@0 120 }
ian@0 121
ian@0 122 if (!acpi_gbl_FADT->xpm_tmr_blk.address) {
ian@0 123 acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0,
ian@0 124 ACPI_FADT_OFFSET(xpm_tmr_blk.
ian@0 125 address));
ian@0 126 }
ian@0 127
ian@0 128 if ((acpi_gbl_FADT->xpm2_cnt_blk.address &&
ian@0 129 !acpi_gbl_FADT->pm2_cnt_len)) {
ian@0 130 acpi_ut_fadt_register_error("PM2_CNT_LEN",
ian@0 131 (u32) acpi_gbl_FADT->pm2_cnt_len,
ian@0 132 ACPI_FADT_OFFSET(pm2_cnt_len));
ian@0 133 }
ian@0 134
ian@0 135 if (acpi_gbl_FADT->pm_tm_len < 4) {
ian@0 136 acpi_ut_fadt_register_error("PM_TM_LEN",
ian@0 137 (u32) acpi_gbl_FADT->pm_tm_len,
ian@0 138 ACPI_FADT_OFFSET(pm_tm_len));
ian@0 139 }
ian@0 140
ian@0 141 /* Length of GPE blocks must be a multiple of 2 */
ian@0 142
ian@0 143 if (acpi_gbl_FADT->xgpe0_blk.address &&
ian@0 144 (acpi_gbl_FADT->gpe0_blk_len & 1)) {
ian@0 145 acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN",
ian@0 146 (u32) acpi_gbl_FADT->gpe0_blk_len,
ian@0 147 ACPI_FADT_OFFSET(gpe0_blk_len));
ian@0 148 }
ian@0 149
ian@0 150 if (acpi_gbl_FADT->xgpe1_blk.address &&
ian@0 151 (acpi_gbl_FADT->gpe1_blk_len & 1)) {
ian@0 152 acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN",
ian@0 153 (u32) acpi_gbl_FADT->gpe1_blk_len,
ian@0 154 ACPI_FADT_OFFSET(gpe1_blk_len));
ian@0 155 }
ian@0 156
ian@0 157 return (AE_OK);
ian@0 158 }
ian@0 159
ian@0 160 /******************************************************************************
ian@0 161 *
ian@0 162 * FUNCTION: acpi_ut_terminate
ian@0 163 *
ian@0 164 * PARAMETERS: none
ian@0 165 *
ian@0 166 * RETURN: none
ian@0 167 *
ian@0 168 * DESCRIPTION: Free global memory
ian@0 169 *
ian@0 170 ******************************************************************************/
ian@0 171
ian@0 172 static void acpi_ut_terminate(void)
ian@0 173 {
ian@0 174 struct acpi_gpe_block_info *gpe_block;
ian@0 175 struct acpi_gpe_block_info *next_gpe_block;
ian@0 176 struct acpi_gpe_xrupt_info *gpe_xrupt_info;
ian@0 177 struct acpi_gpe_xrupt_info *next_gpe_xrupt_info;
ian@0 178
ian@0 179 ACPI_FUNCTION_TRACE(ut_terminate);
ian@0 180
ian@0 181 /* Free global tables, etc. */
ian@0 182 /* Free global GPE blocks and related info structures */
ian@0 183
ian@0 184 gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
ian@0 185 while (gpe_xrupt_info) {
ian@0 186 gpe_block = gpe_xrupt_info->gpe_block_list_head;
ian@0 187 while (gpe_block) {
ian@0 188 next_gpe_block = gpe_block->next;
ian@0 189 ACPI_FREE(gpe_block->event_info);
ian@0 190 ACPI_FREE(gpe_block->register_info);
ian@0 191 ACPI_FREE(gpe_block);
ian@0 192
ian@0 193 gpe_block = next_gpe_block;
ian@0 194 }
ian@0 195 next_gpe_xrupt_info = gpe_xrupt_info->next;
ian@0 196 ACPI_FREE(gpe_xrupt_info);
ian@0 197 gpe_xrupt_info = next_gpe_xrupt_info;
ian@0 198 }
ian@0 199
ian@0 200 return_VOID;
ian@0 201 }
ian@0 202
ian@0 203 /*******************************************************************************
ian@0 204 *
ian@0 205 * FUNCTION: acpi_ut_subsystem_shutdown
ian@0 206 *
ian@0 207 * PARAMETERS: none
ian@0 208 *
ian@0 209 * RETURN: none
ian@0 210 *
ian@0 211 * DESCRIPTION: Shutdown the various subsystems. Don't delete the mutex
ian@0 212 * objects here -- because the AML debugger may be still running.
ian@0 213 *
ian@0 214 ******************************************************************************/
ian@0 215
ian@0 216 void acpi_ut_subsystem_shutdown(void)
ian@0 217 {
ian@0 218
ian@0 219 ACPI_FUNCTION_TRACE(ut_subsystem_shutdown);
ian@0 220
ian@0 221 /* Just exit if subsystem is already shutdown */
ian@0 222
ian@0 223 if (acpi_gbl_shutdown) {
ian@0 224 ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
ian@0 225 return_VOID;
ian@0 226 }
ian@0 227
ian@0 228 /* Subsystem appears active, go ahead and shut it down */
ian@0 229
ian@0 230 acpi_gbl_shutdown = TRUE;
ian@0 231 acpi_gbl_startup_flags = 0;
ian@0 232 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
ian@0 233
ian@0 234 /* Close the acpi_event Handling */
ian@0 235
ian@0 236 acpi_ev_terminate();
ian@0 237
ian@0 238 /* Close the Namespace */
ian@0 239
ian@0 240 acpi_ns_terminate();
ian@0 241
ian@0 242 /* Close the globals */
ian@0 243
ian@0 244 acpi_ut_terminate();
ian@0 245
ian@0 246 /* Purge the local caches */
ian@0 247
ian@0 248 (void)acpi_ut_delete_caches();
ian@0 249 return_VOID;
ian@0 250 }