ia64/linux-2.6.18-xen.hg

view drivers/acpi/event.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 * event.c - exporting ACPI events via procfs
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 */
9 #include <linux/spinlock.h>
10 #include <linux/proc_fs.h>
11 #include <linux/init.h>
12 #include <linux/poll.h>
13 #include <acpi/acpi_drivers.h>
15 #define _COMPONENT ACPI_SYSTEM_COMPONENT
16 ACPI_MODULE_NAME("event")
18 /* Global vars for handling event proc entry */
19 static DEFINE_SPINLOCK(acpi_system_event_lock);
20 int event_is_open = 0;
21 extern struct list_head acpi_bus_event_list;
22 extern wait_queue_head_t acpi_bus_event_queue;
24 static int acpi_system_open_event(struct inode *inode, struct file *file)
25 {
26 spin_lock_irq(&acpi_system_event_lock);
28 if (event_is_open)
29 goto out_busy;
31 event_is_open = 1;
33 spin_unlock_irq(&acpi_system_event_lock);
34 return 0;
36 out_busy:
37 spin_unlock_irq(&acpi_system_event_lock);
38 return -EBUSY;
39 }
41 static ssize_t
42 acpi_system_read_event(struct file *file, char __user * buffer, size_t count,
43 loff_t * ppos)
44 {
45 int result = 0;
46 struct acpi_bus_event event;
47 static char str[ACPI_MAX_STRING];
48 static int chars_remaining = 0;
49 static char *ptr;
52 if (!chars_remaining) {
53 memset(&event, 0, sizeof(struct acpi_bus_event));
55 if ((file->f_flags & O_NONBLOCK)
56 && (list_empty(&acpi_bus_event_list)))
57 return -EAGAIN;
59 result = acpi_bus_receive_event(&event);
60 if (result)
61 return result;
63 chars_remaining = sprintf(str, "%s %s %08x %08x\n",
64 event.device_class ? event.
65 device_class : "<unknown>",
66 event.bus_id ? event.
67 bus_id : "<unknown>", event.type,
68 event.data);
69 ptr = str;
70 }
72 if (chars_remaining < count) {
73 count = chars_remaining;
74 }
76 if (copy_to_user(buffer, ptr, count))
77 return -EFAULT;
79 *ppos += count;
80 chars_remaining -= count;
81 ptr += count;
83 return count;
84 }
86 static int acpi_system_close_event(struct inode *inode, struct file *file)
87 {
88 spin_lock_irq(&acpi_system_event_lock);
89 event_is_open = 0;
90 spin_unlock_irq(&acpi_system_event_lock);
91 return 0;
92 }
94 static unsigned int acpi_system_poll_event(struct file *file, poll_table * wait)
95 {
96 poll_wait(file, &acpi_bus_event_queue, wait);
97 if (!list_empty(&acpi_bus_event_list))
98 return POLLIN | POLLRDNORM;
99 return 0;
100 }
102 static const struct file_operations acpi_system_event_ops = {
103 .open = acpi_system_open_event,
104 .read = acpi_system_read_event,
105 .release = acpi_system_close_event,
106 .poll = acpi_system_poll_event,
107 };
109 static int __init acpi_event_init(void)
110 {
111 struct proc_dir_entry *entry;
112 int error = 0;
115 if (acpi_disabled)
116 return 0;
118 /* 'event' [R] */
119 entry = create_proc_entry("event", S_IRUSR, acpi_root_dir);
120 if (entry)
121 entry->proc_fops = &acpi_system_event_ops;
122 else {
123 error = -ENODEV;
124 }
125 return error;
126 }
128 subsys_initcall(acpi_event_init);