ia64/linux-2.6.18-xen.hg

annotate drivers/acpi/utilities/utmutex.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: utmutex - local mutex support
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
ian@0 46 #define _COMPONENT ACPI_UTILITIES
ian@0 47 ACPI_MODULE_NAME("utmutex")
ian@0 48
ian@0 49 /* Local prototypes */
ian@0 50 static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
ian@0 51
ian@0 52 static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
ian@0 53
ian@0 54 /*******************************************************************************
ian@0 55 *
ian@0 56 * FUNCTION: acpi_ut_mutex_initialize
ian@0 57 *
ian@0 58 * PARAMETERS: None.
ian@0 59 *
ian@0 60 * RETURN: Status
ian@0 61 *
ian@0 62 * DESCRIPTION: Create the system mutex objects.
ian@0 63 *
ian@0 64 ******************************************************************************/
ian@0 65
ian@0 66 acpi_status acpi_ut_mutex_initialize(void)
ian@0 67 {
ian@0 68 u32 i;
ian@0 69 acpi_status status;
ian@0 70
ian@0 71 ACPI_FUNCTION_TRACE(ut_mutex_initialize);
ian@0 72
ian@0 73 /*
ian@0 74 * Create each of the predefined mutex objects
ian@0 75 */
ian@0 76 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
ian@0 77 status = acpi_ut_create_mutex(i);
ian@0 78 if (ACPI_FAILURE(status)) {
ian@0 79 return_ACPI_STATUS(status);
ian@0 80 }
ian@0 81 }
ian@0 82
ian@0 83 /* Create the spinlocks for use at interrupt level */
ian@0 84
ian@0 85 spin_lock_init(acpi_gbl_gpe_lock);
ian@0 86 spin_lock_init(acpi_gbl_hardware_lock);
ian@0 87
ian@0 88 return_ACPI_STATUS(status);
ian@0 89 }
ian@0 90
ian@0 91 /*******************************************************************************
ian@0 92 *
ian@0 93 * FUNCTION: acpi_ut_mutex_terminate
ian@0 94 *
ian@0 95 * PARAMETERS: None.
ian@0 96 *
ian@0 97 * RETURN: None.
ian@0 98 *
ian@0 99 * DESCRIPTION: Delete all of the system mutex objects.
ian@0 100 *
ian@0 101 ******************************************************************************/
ian@0 102
ian@0 103 void acpi_ut_mutex_terminate(void)
ian@0 104 {
ian@0 105 u32 i;
ian@0 106
ian@0 107 ACPI_FUNCTION_TRACE(ut_mutex_terminate);
ian@0 108
ian@0 109 /*
ian@0 110 * Delete each predefined mutex object
ian@0 111 */
ian@0 112 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
ian@0 113 (void)acpi_ut_delete_mutex(i);
ian@0 114 }
ian@0 115
ian@0 116 /* Delete the spinlocks */
ian@0 117
ian@0 118 acpi_os_delete_lock(acpi_gbl_gpe_lock);
ian@0 119 acpi_os_delete_lock(acpi_gbl_hardware_lock);
ian@0 120 return_VOID;
ian@0 121 }
ian@0 122
ian@0 123 /*******************************************************************************
ian@0 124 *
ian@0 125 * FUNCTION: acpi_ut_create_mutex
ian@0 126 *
ian@0 127 * PARAMETERS: mutex_iD - ID of the mutex to be created
ian@0 128 *
ian@0 129 * RETURN: Status
ian@0 130 *
ian@0 131 * DESCRIPTION: Create a mutex object.
ian@0 132 *
ian@0 133 ******************************************************************************/
ian@0 134
ian@0 135 static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
ian@0 136 {
ian@0 137 acpi_status status = AE_OK;
ian@0 138
ian@0 139 ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
ian@0 140
ian@0 141 if (mutex_id > ACPI_MAX_MUTEX) {
ian@0 142 return_ACPI_STATUS(AE_BAD_PARAMETER);
ian@0 143 }
ian@0 144
ian@0 145 if (!acpi_gbl_mutex_info[mutex_id].mutex) {
ian@0 146 status =
ian@0 147 acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
ian@0 148 acpi_gbl_mutex_info[mutex_id].thread_id =
ian@0 149 ACPI_MUTEX_NOT_ACQUIRED;
ian@0 150 acpi_gbl_mutex_info[mutex_id].use_count = 0;
ian@0 151 }
ian@0 152
ian@0 153 return_ACPI_STATUS(status);
ian@0 154 }
ian@0 155
ian@0 156 /*******************************************************************************
ian@0 157 *
ian@0 158 * FUNCTION: acpi_ut_delete_mutex
ian@0 159 *
ian@0 160 * PARAMETERS: mutex_iD - ID of the mutex to be deleted
ian@0 161 *
ian@0 162 * RETURN: Status
ian@0 163 *
ian@0 164 * DESCRIPTION: Delete a mutex object.
ian@0 165 *
ian@0 166 ******************************************************************************/
ian@0 167
ian@0 168 static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
ian@0 169 {
ian@0 170
ian@0 171 ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
ian@0 172
ian@0 173 if (mutex_id > ACPI_MAX_MUTEX) {
ian@0 174 return_ACPI_STATUS(AE_BAD_PARAMETER);
ian@0 175 }
ian@0 176
ian@0 177 acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
ian@0 178
ian@0 179 acpi_gbl_mutex_info[mutex_id].mutex = NULL;
ian@0 180 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
ian@0 181
ian@0 182 return_ACPI_STATUS(AE_OK);
ian@0 183 }
ian@0 184
ian@0 185 /*******************************************************************************
ian@0 186 *
ian@0 187 * FUNCTION: acpi_ut_acquire_mutex
ian@0 188 *
ian@0 189 * PARAMETERS: mutex_iD - ID of the mutex to be acquired
ian@0 190 *
ian@0 191 * RETURN: Status
ian@0 192 *
ian@0 193 * DESCRIPTION: Acquire a mutex object.
ian@0 194 *
ian@0 195 ******************************************************************************/
ian@0 196
ian@0 197 acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
ian@0 198 {
ian@0 199 acpi_status status;
ian@0 200 acpi_thread_id this_thread_id;
ian@0 201
ian@0 202 ACPI_FUNCTION_NAME(ut_acquire_mutex);
ian@0 203
ian@0 204 if (mutex_id > ACPI_MAX_MUTEX) {
ian@0 205 return (AE_BAD_PARAMETER);
ian@0 206 }
ian@0 207
ian@0 208 this_thread_id = acpi_os_get_thread_id();
ian@0 209
ian@0 210 #ifdef ACPI_MUTEX_DEBUG
ian@0 211 {
ian@0 212 u32 i;
ian@0 213 /*
ian@0 214 * Mutex debug code, for internal debugging only.
ian@0 215 *
ian@0 216 * Deadlock prevention. Check if this thread owns any mutexes of value
ian@0 217 * greater than or equal to this one. If so, the thread has violated
ian@0 218 * the mutex ordering rule. This indicates a coding error somewhere in
ian@0 219 * the ACPI subsystem code.
ian@0 220 */
ian@0 221 for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) {
ian@0 222 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
ian@0 223 if (i == mutex_id) {
ian@0 224 ACPI_ERROR((AE_INFO,
ian@0 225 "Mutex [%s] already acquired by this thread [%X]",
ian@0 226 acpi_ut_get_mutex_name
ian@0 227 (mutex_id),
ian@0 228 this_thread_id));
ian@0 229
ian@0 230 return (AE_ALREADY_ACQUIRED);
ian@0 231 }
ian@0 232
ian@0 233 ACPI_ERROR((AE_INFO,
ian@0 234 "Invalid acquire order: Thread %X owns [%s], wants [%s]",
ian@0 235 this_thread_id,
ian@0 236 acpi_ut_get_mutex_name(i),
ian@0 237 acpi_ut_get_mutex_name(mutex_id)));
ian@0 238
ian@0 239 return (AE_ACQUIRE_DEADLOCK);
ian@0 240 }
ian@0 241 }
ian@0 242 }
ian@0 243 #endif
ian@0 244
ian@0 245 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
ian@0 246 "Thread %X attempting to acquire Mutex [%s]\n",
ian@0 247 (u32) this_thread_id, acpi_ut_get_mutex_name(mutex_id)));
ian@0 248
ian@0 249 status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
ian@0 250 ACPI_WAIT_FOREVER);
ian@0 251 if (ACPI_SUCCESS(status)) {
ian@0 252 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
ian@0 253 "Thread %X acquired Mutex [%s]\n",
ian@0 254 (u32) this_thread_id,
ian@0 255 acpi_ut_get_mutex_name(mutex_id)));
ian@0 256
ian@0 257 acpi_gbl_mutex_info[mutex_id].use_count++;
ian@0 258 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
ian@0 259 } else {
ian@0 260 ACPI_EXCEPTION((AE_INFO, status,
ian@0 261 "Thread %X could not acquire Mutex [%X]",
ian@0 262 (u32) this_thread_id, mutex_id));
ian@0 263 }
ian@0 264
ian@0 265 return (status);
ian@0 266 }
ian@0 267
ian@0 268 /*******************************************************************************
ian@0 269 *
ian@0 270 * FUNCTION: acpi_ut_release_mutex
ian@0 271 *
ian@0 272 * PARAMETERS: mutex_iD - ID of the mutex to be released
ian@0 273 *
ian@0 274 * RETURN: Status
ian@0 275 *
ian@0 276 * DESCRIPTION: Release a mutex object.
ian@0 277 *
ian@0 278 ******************************************************************************/
ian@0 279
ian@0 280 acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
ian@0 281 {
ian@0 282 acpi_thread_id this_thread_id;
ian@0 283
ian@0 284 ACPI_FUNCTION_NAME(ut_release_mutex);
ian@0 285
ian@0 286 this_thread_id = acpi_os_get_thread_id();
ian@0 287 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
ian@0 288 "Thread %X releasing Mutex [%s]\n", (u32) this_thread_id,
ian@0 289 acpi_ut_get_mutex_name(mutex_id)));
ian@0 290
ian@0 291 if (mutex_id > ACPI_MAX_MUTEX) {
ian@0 292 return (AE_BAD_PARAMETER);
ian@0 293 }
ian@0 294
ian@0 295 /*
ian@0 296 * Mutex must be acquired in order to release it!
ian@0 297 */
ian@0 298 if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
ian@0 299 ACPI_ERROR((AE_INFO,
ian@0 300 "Mutex [%X] is not acquired, cannot release",
ian@0 301 mutex_id));
ian@0 302
ian@0 303 return (AE_NOT_ACQUIRED);
ian@0 304 }
ian@0 305 #ifdef ACPI_MUTEX_DEBUG
ian@0 306 {
ian@0 307 u32 i;
ian@0 308 /*
ian@0 309 * Mutex debug code, for internal debugging only.
ian@0 310 *
ian@0 311 * Deadlock prevention. Check if this thread owns any mutexes of value
ian@0 312 * greater than this one. If so, the thread has violated the mutex
ian@0 313 * ordering rule. This indicates a coding error somewhere in
ian@0 314 * the ACPI subsystem code.
ian@0 315 */
ian@0 316 for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) {
ian@0 317 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
ian@0 318 if (i == mutex_id) {
ian@0 319 continue;
ian@0 320 }
ian@0 321
ian@0 322 ACPI_ERROR((AE_INFO,
ian@0 323 "Invalid release order: owns [%s], releasing [%s]",
ian@0 324 acpi_ut_get_mutex_name(i),
ian@0 325 acpi_ut_get_mutex_name(mutex_id)));
ian@0 326
ian@0 327 return (AE_RELEASE_DEADLOCK);
ian@0 328 }
ian@0 329 }
ian@0 330 }
ian@0 331 #endif
ian@0 332
ian@0 333 /* Mark unlocked FIRST */
ian@0 334
ian@0 335 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
ian@0 336
ian@0 337 acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
ian@0 338 return (AE_OK);
ian@0 339 }