ia64/linux-2.6.18-xen.hg

view drivers/acpi/power.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 * acpi_power.c - ACPI Bus Power Management ($Revision: 39 $)
3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */
26 /*
27 * ACPI power-managed devices may be controlled in two ways:
28 * 1. via "Device Specific (D-State) Control"
29 * 2. via "Power Resource Control".
30 * This module is used to manage devices relying on Power Resource Control.
31 *
32 * An ACPI "power resource object" describes a software controllable power
33 * plane, clock plane, or other resource used by a power managed device.
34 * A device may rely on multiple power resources, and a power resource
35 * may be shared by multiple devices.
36 */
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/init.h>
41 #include <linux/types.h>
42 #include <linux/proc_fs.h>
43 #include <linux/seq_file.h>
44 #include <acpi/acpi_bus.h>
45 #include <acpi/acpi_drivers.h>
47 #define _COMPONENT ACPI_POWER_COMPONENT
48 ACPI_MODULE_NAME("acpi_power")
49 #define ACPI_POWER_COMPONENT 0x00800000
50 #define ACPI_POWER_CLASS "power_resource"
51 #define ACPI_POWER_DRIVER_NAME "ACPI Power Resource Driver"
52 #define ACPI_POWER_DEVICE_NAME "Power Resource"
53 #define ACPI_POWER_FILE_INFO "info"
54 #define ACPI_POWER_FILE_STATUS "state"
55 #define ACPI_POWER_RESOURCE_STATE_OFF 0x00
56 #define ACPI_POWER_RESOURCE_STATE_ON 0x01
57 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
58 static int acpi_power_add(struct acpi_device *device);
59 static int acpi_power_remove(struct acpi_device *device, int type);
60 static int acpi_power_open_fs(struct inode *inode, struct file *file);
62 static struct acpi_driver acpi_power_driver = {
63 .name = ACPI_POWER_DRIVER_NAME,
64 .class = ACPI_POWER_CLASS,
65 .ids = ACPI_POWER_HID,
66 .ops = {
67 .add = acpi_power_add,
68 .remove = acpi_power_remove,
69 },
70 };
72 struct acpi_power_resource {
73 struct acpi_device * device;
74 acpi_bus_id name;
75 u32 system_level;
76 u32 order;
77 int state;
78 int references;
79 };
81 static struct list_head acpi_power_resource_list;
83 static const struct file_operations acpi_power_fops = {
84 .open = acpi_power_open_fs,
85 .read = seq_read,
86 .llseek = seq_lseek,
87 .release = single_release,
88 };
90 /* --------------------------------------------------------------------------
91 Power Resource Management
92 -------------------------------------------------------------------------- */
94 static int
95 acpi_power_get_context(acpi_handle handle,
96 struct acpi_power_resource **resource)
97 {
98 int result = 0;
99 struct acpi_device *device = NULL;
102 if (!resource)
103 return -ENODEV;
105 result = acpi_bus_get_device(handle, &device);
106 if (result) {
107 printk(KERN_WARNING PREFIX "Getting context [%p]\n", handle);
108 return result;
109 }
111 *resource = (struct acpi_power_resource *)acpi_driver_data(device);
112 if (!resource)
113 return -ENODEV;
115 return 0;
116 }
118 static int acpi_power_get_state(struct acpi_power_resource *resource)
119 {
120 acpi_status status = AE_OK;
121 unsigned long sta = 0;
124 if (!resource)
125 return -EINVAL;
127 status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta);
128 if (ACPI_FAILURE(status))
129 return -ENODEV;
131 if (sta & 0x01)
132 resource->state = ACPI_POWER_RESOURCE_STATE_ON;
133 else
134 resource->state = ACPI_POWER_RESOURCE_STATE_OFF;
136 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
137 resource->name, resource->state ? "on" : "off"));
139 return 0;
140 }
142 static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
143 {
144 int result = 0;
145 struct acpi_power_resource *resource = NULL;
146 u32 i = 0;
149 if (!list || !state)
150 return -EINVAL;
152 /* The state of the list is 'on' IFF all resources are 'on'. */
154 for (i = 0; i < list->count; i++) {
155 result = acpi_power_get_context(list->handles[i], &resource);
156 if (result)
157 return result;
158 result = acpi_power_get_state(resource);
159 if (result)
160 return result;
162 *state = resource->state;
164 if (*state != ACPI_POWER_RESOURCE_STATE_ON)
165 break;
166 }
168 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n",
169 *state ? "on" : "off"));
171 return result;
172 }
174 static int acpi_power_on(acpi_handle handle)
175 {
176 int result = 0;
177 acpi_status status = AE_OK;
178 struct acpi_device *device = NULL;
179 struct acpi_power_resource *resource = NULL;
182 result = acpi_power_get_context(handle, &resource);
183 if (result)
184 return result;
186 resource->references++;
188 if ((resource->references > 1)
189 || (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) {
190 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n",
191 resource->name));
192 return 0;
193 }
195 status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
196 if (ACPI_FAILURE(status))
197 return -ENODEV;
199 result = acpi_power_get_state(resource);
200 if (result)
201 return result;
202 if (resource->state != ACPI_POWER_RESOURCE_STATE_ON)
203 return -ENOEXEC;
205 /* Update the power resource's _device_ power state */
206 device = resource->device;
207 resource->device->power.state = ACPI_STATE_D0;
209 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n",
210 resource->name));
212 return 0;
213 }
215 static int acpi_power_off_device(acpi_handle handle)
216 {
217 int result = 0;
218 acpi_status status = AE_OK;
219 struct acpi_device *device = NULL;
220 struct acpi_power_resource *resource = NULL;
223 result = acpi_power_get_context(handle, &resource);
224 if (result)
225 return result;
227 if (resource->references)
228 resource->references--;
230 if (resource->references) {
231 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
232 "Resource [%s] is still in use, dereferencing\n",
233 device->pnp.bus_id));
234 return 0;
235 }
237 if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
238 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
239 device->pnp.bus_id));
240 return 0;
241 }
243 status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
244 if (ACPI_FAILURE(status))
245 return -ENODEV;
247 result = acpi_power_get_state(resource);
248 if (result)
249 return result;
250 if (resource->state != ACPI_POWER_RESOURCE_STATE_OFF)
251 return -ENOEXEC;
253 /* Update the power resource's _device_ power state */
254 device = resource->device;
255 device->power.state = ACPI_STATE_D3;
257 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n",
258 resource->name));
260 return 0;
261 }
263 /*
264 * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229):
265 * 1. Power on the power resources required for the wakeup device
266 * 2. Enable _PSW (power state wake) for the device if present
267 */
268 int acpi_enable_wakeup_device_power(struct acpi_device *dev)
269 {
270 union acpi_object arg = { ACPI_TYPE_INTEGER };
271 struct acpi_object_list arg_list = { 1, &arg };
272 acpi_status status = AE_OK;
273 int i;
274 int ret = 0;
276 if (!dev || !dev->wakeup.flags.valid)
277 return -1;
279 arg.integer.value = 1;
280 /* Open power resource */
281 for (i = 0; i < dev->wakeup.resources.count; i++) {
282 ret = acpi_power_on(dev->wakeup.resources.handles[i]);
283 if (ret) {
284 printk(KERN_ERR PREFIX "Transition power state\n");
285 dev->wakeup.flags.valid = 0;
286 return -1;
287 }
288 }
290 /* Execute PSW */
291 status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
292 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
293 printk(KERN_ERR PREFIX "Evaluate _PSW\n");
294 dev->wakeup.flags.valid = 0;
295 ret = -1;
296 }
298 return ret;
299 }
301 /*
302 * Shutdown a wakeup device, counterpart of above method
303 * 1. Disable _PSW (power state wake)
304 * 2. Shutdown down the power resources
305 */
306 int acpi_disable_wakeup_device_power(struct acpi_device *dev)
307 {
308 union acpi_object arg = { ACPI_TYPE_INTEGER };
309 struct acpi_object_list arg_list = { 1, &arg };
310 acpi_status status = AE_OK;
311 int i;
312 int ret = 0;
315 if (!dev || !dev->wakeup.flags.valid)
316 return -1;
318 arg.integer.value = 0;
319 /* Execute PSW */
320 status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
321 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
322 printk(KERN_ERR PREFIX "Evaluate _PSW\n");
323 dev->wakeup.flags.valid = 0;
324 return -1;
325 }
327 /* Close power resource */
328 for (i = 0; i < dev->wakeup.resources.count; i++) {
329 ret = acpi_power_off_device(dev->wakeup.resources.handles[i]);
330 if (ret) {
331 printk(KERN_ERR PREFIX "Transition power state\n");
332 dev->wakeup.flags.valid = 0;
333 return -1;
334 }
335 }
337 return ret;
338 }
340 /* --------------------------------------------------------------------------
341 Device Power Management
342 -------------------------------------------------------------------------- */
344 int acpi_power_get_inferred_state(struct acpi_device *device)
345 {
346 int result = 0;
347 struct acpi_handle_list *list = NULL;
348 int list_state = 0;
349 int i = 0;
352 if (!device)
353 return -EINVAL;
355 device->power.state = ACPI_STATE_UNKNOWN;
357 /*
358 * We know a device's inferred power state when all the resources
359 * required for a given D-state are 'on'.
360 */
361 for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) {
362 list = &device->power.states[i].resources;
363 if (list->count < 1)
364 continue;
366 result = acpi_power_get_list_state(list, &list_state);
367 if (result)
368 return result;
370 if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
371 device->power.state = i;
372 return 0;
373 }
374 }
376 device->power.state = ACPI_STATE_D3;
378 return 0;
379 }
381 int acpi_power_transition(struct acpi_device *device, int state)
382 {
383 int result = 0;
384 struct acpi_handle_list *cl = NULL; /* Current Resources */
385 struct acpi_handle_list *tl = NULL; /* Target Resources */
386 int i = 0;
389 if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
390 return -EINVAL;
392 if ((device->power.state < ACPI_STATE_D0)
393 || (device->power.state > ACPI_STATE_D3))
394 return -ENODEV;
396 cl = &device->power.states[device->power.state].resources;
397 tl = &device->power.states[state].resources;
399 device->power.state = ACPI_STATE_UNKNOWN;
401 if (!cl->count && !tl->count) {
402 result = -ENODEV;
403 goto end;
404 }
406 /* TBD: Resources must be ordered. */
408 /*
409 * First we reference all power resources required in the target list
410 * (e.g. so the device doesn't lose power while transitioning).
411 */
412 for (i = 0; i < tl->count; i++) {
413 result = acpi_power_on(tl->handles[i]);
414 if (result)
415 goto end;
416 }
418 /*
419 * Then we dereference all power resources used in the current list.
420 */
421 for (i = 0; i < cl->count; i++) {
422 result = acpi_power_off_device(cl->handles[i]);
423 if (result)
424 goto end;
425 }
427 /* We shouldn't change the state till all above operations succeed */
428 device->power.state = state;
429 end:
430 if (result)
431 printk(KERN_WARNING PREFIX "Transitioning device [%s] to D%d\n",
432 device->pnp.bus_id, state);
434 return result;
435 }
437 /* --------------------------------------------------------------------------
438 FS Interface (/proc)
439 -------------------------------------------------------------------------- */
441 static struct proc_dir_entry *acpi_power_dir;
443 static int acpi_power_seq_show(struct seq_file *seq, void *offset)
444 {
445 struct acpi_power_resource *resource = NULL;
448 resource = (struct acpi_power_resource *)seq->private;
450 if (!resource)
451 goto end;
453 seq_puts(seq, "state: ");
454 switch (resource->state) {
455 case ACPI_POWER_RESOURCE_STATE_ON:
456 seq_puts(seq, "on\n");
457 break;
458 case ACPI_POWER_RESOURCE_STATE_OFF:
459 seq_puts(seq, "off\n");
460 break;
461 default:
462 seq_puts(seq, "unknown\n");
463 break;
464 }
466 seq_printf(seq, "system level: S%d\n"
467 "order: %d\n"
468 "reference count: %d\n",
469 resource->system_level,
470 resource->order, resource->references);
472 end:
473 return 0;
474 }
476 static int acpi_power_open_fs(struct inode *inode, struct file *file)
477 {
478 return single_open(file, acpi_power_seq_show, PDE(inode)->data);
479 }
481 static int acpi_power_add_fs(struct acpi_device *device)
482 {
483 struct proc_dir_entry *entry = NULL;
486 if (!device)
487 return -EINVAL;
489 if (!acpi_device_dir(device)) {
490 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
491 acpi_power_dir);
492 if (!acpi_device_dir(device))
493 return -ENODEV;
494 }
496 /* 'status' [R] */
497 entry = create_proc_entry(ACPI_POWER_FILE_STATUS,
498 S_IRUGO, acpi_device_dir(device));
499 if (!entry)
500 return -EIO;
501 else {
502 entry->proc_fops = &acpi_power_fops;
503 entry->data = acpi_driver_data(device);
504 }
506 return 0;
507 }
509 static int acpi_power_remove_fs(struct acpi_device *device)
510 {
512 if (acpi_device_dir(device)) {
513 remove_proc_entry(ACPI_POWER_FILE_STATUS,
514 acpi_device_dir(device));
515 remove_proc_entry(acpi_device_bid(device), acpi_power_dir);
516 acpi_device_dir(device) = NULL;
517 }
519 return 0;
520 }
522 /* --------------------------------------------------------------------------
523 Driver Interface
524 -------------------------------------------------------------------------- */
526 static int acpi_power_add(struct acpi_device *device)
527 {
528 int result = 0;
529 acpi_status status = AE_OK;
530 struct acpi_power_resource *resource = NULL;
531 union acpi_object acpi_object;
532 struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };
535 if (!device)
536 return -EINVAL;
538 resource = kmalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
539 if (!resource)
540 return -ENOMEM;
541 memset(resource, 0, sizeof(struct acpi_power_resource));
543 resource->device = device;
544 strcpy(resource->name, device->pnp.bus_id);
545 strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
546 strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
547 acpi_driver_data(device) = resource;
549 /* Evalute the object to get the system level and resource order. */
550 status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer);
551 if (ACPI_FAILURE(status)) {
552 result = -ENODEV;
553 goto end;
554 }
555 resource->system_level = acpi_object.power_resource.system_level;
556 resource->order = acpi_object.power_resource.resource_order;
558 result = acpi_power_get_state(resource);
559 if (result)
560 goto end;
562 switch (resource->state) {
563 case ACPI_POWER_RESOURCE_STATE_ON:
564 device->power.state = ACPI_STATE_D0;
565 break;
566 case ACPI_POWER_RESOURCE_STATE_OFF:
567 device->power.state = ACPI_STATE_D3;
568 break;
569 default:
570 device->power.state = ACPI_STATE_UNKNOWN;
571 break;
572 }
574 result = acpi_power_add_fs(device);
575 if (result)
576 goto end;
578 printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
579 acpi_device_bid(device), resource->state ? "on" : "off");
581 end:
582 if (result)
583 kfree(resource);
585 return result;
586 }
588 static int acpi_power_remove(struct acpi_device *device, int type)
589 {
590 struct acpi_power_resource *resource = NULL;
593 if (!device || !acpi_driver_data(device))
594 return -EINVAL;
596 resource = (struct acpi_power_resource *)acpi_driver_data(device);
598 acpi_power_remove_fs(device);
600 kfree(resource);
602 return 0;
603 }
605 static int __init acpi_power_init(void)
606 {
607 int result = 0;
610 if (acpi_disabled)
611 return 0;
613 INIT_LIST_HEAD(&acpi_power_resource_list);
615 acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);
616 if (!acpi_power_dir)
617 return -ENODEV;
619 result = acpi_bus_register_driver(&acpi_power_driver);
620 if (result < 0) {
621 remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir);
622 return -ENODEV;
623 }
625 return 0;
626 }
628 subsys_initcall(acpi_power_init);