ia64/linux-2.6.18-xen.hg

view drivers/acpi/debug.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 * debug.c - ACPI debug interface to userspace.
3 */
5 #include <linux/proc_fs.h>
6 #include <linux/init.h>
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/moduleparam.h>
10 #include <asm/uaccess.h>
11 #include <acpi/acpi_drivers.h>
12 #include <acpi/acglobal.h>
14 #define _COMPONENT ACPI_SYSTEM_COMPONENT
15 ACPI_MODULE_NAME("debug")
16 #define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer"
17 #define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level"
18 #ifdef MODULE_PARAM_PREFIX
19 #undef MODULE_PARAM_PREFIX
20 #endif
21 #define MODULE_PARAM_PREFIX
22 module_param(acpi_dbg_layer, uint, 0400);
23 module_param(acpi_dbg_level, uint, 0400);
25 struct acpi_dlayer {
26 const char *name;
27 unsigned long value;
28 };
29 struct acpi_dlevel {
30 const char *name;
31 unsigned long value;
32 };
33 #define ACPI_DEBUG_INIT(v) { .name = #v, .value = v }
35 static const struct acpi_dlayer acpi_debug_layers[] = {
36 ACPI_DEBUG_INIT(ACPI_UTILITIES),
37 ACPI_DEBUG_INIT(ACPI_HARDWARE),
38 ACPI_DEBUG_INIT(ACPI_EVENTS),
39 ACPI_DEBUG_INIT(ACPI_TABLES),
40 ACPI_DEBUG_INIT(ACPI_NAMESPACE),
41 ACPI_DEBUG_INIT(ACPI_PARSER),
42 ACPI_DEBUG_INIT(ACPI_DISPATCHER),
43 ACPI_DEBUG_INIT(ACPI_EXECUTER),
44 ACPI_DEBUG_INIT(ACPI_RESOURCES),
45 ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER),
46 ACPI_DEBUG_INIT(ACPI_OS_SERVICES),
47 ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER),
48 ACPI_DEBUG_INIT(ACPI_COMPILER),
49 ACPI_DEBUG_INIT(ACPI_TOOLS),
50 };
52 static const struct acpi_dlevel acpi_debug_levels[] = {
53 ACPI_DEBUG_INIT(ACPI_LV_ERROR),
54 ACPI_DEBUG_INIT(ACPI_LV_WARN),
55 ACPI_DEBUG_INIT(ACPI_LV_INIT),
56 ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
57 ACPI_DEBUG_INIT(ACPI_LV_INFO),
59 ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES),
60 ACPI_DEBUG_INIT(ACPI_LV_PARSE),
61 ACPI_DEBUG_INIT(ACPI_LV_LOAD),
62 ACPI_DEBUG_INIT(ACPI_LV_DISPATCH),
63 ACPI_DEBUG_INIT(ACPI_LV_EXEC),
64 ACPI_DEBUG_INIT(ACPI_LV_NAMES),
65 ACPI_DEBUG_INIT(ACPI_LV_OPREGION),
66 ACPI_DEBUG_INIT(ACPI_LV_BFIELD),
67 ACPI_DEBUG_INIT(ACPI_LV_TABLES),
68 ACPI_DEBUG_INIT(ACPI_LV_VALUES),
69 ACPI_DEBUG_INIT(ACPI_LV_OBJECTS),
70 ACPI_DEBUG_INIT(ACPI_LV_RESOURCES),
71 ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS),
72 ACPI_DEBUG_INIT(ACPI_LV_PACKAGE),
74 ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS),
75 ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS),
76 ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS),
78 ACPI_DEBUG_INIT(ACPI_LV_MUTEX),
79 ACPI_DEBUG_INIT(ACPI_LV_THREADS),
80 ACPI_DEBUG_INIT(ACPI_LV_IO),
81 ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS),
83 ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE),
84 ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO),
85 ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES),
86 ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
87 };
89 static int
90 acpi_system_read_debug(char *page,
91 char **start, off_t off, int count, int *eof, void *data)
92 {
93 char *p = page;
94 int size = 0;
95 unsigned int i;
97 if (off != 0)
98 goto end;
100 p += sprintf(p, "%-25s\tHex SET\n", "Description");
102 switch ((unsigned long)data) {
103 case 0:
104 for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) {
105 p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
106 acpi_debug_layers[i].name,
107 acpi_debug_layers[i].value,
108 (acpi_dbg_layer & acpi_debug_layers[i].
109 value) ? '*' : ' ');
110 }
111 p += sprintf(p, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
112 ACPI_ALL_DRIVERS,
113 (acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
114 ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer &
115 ACPI_ALL_DRIVERS) ==
116 0 ? ' ' : '-');
117 p += sprintf(p,
118 "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n",
119 acpi_dbg_layer);
120 break;
121 case 1:
122 for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
123 p += sprintf(p, "%-25s\t0x%08lX [%c]\n",
124 acpi_debug_levels[i].name,
125 acpi_debug_levels[i].value,
126 (acpi_dbg_level & acpi_debug_levels[i].
127 value) ? '*' : ' ');
128 }
129 p += sprintf(p, "--\ndebug_level = 0x%08X (* = enabled)\n",
130 acpi_dbg_level);
131 break;
132 default:
133 p += sprintf(p, "Invalid debug option\n");
134 break;
135 }
137 end:
138 size = (p - page);
139 if (size <= off + count)
140 *eof = 1;
141 *start = page + off;
142 size -= off;
143 if (size > count)
144 size = count;
145 if (size < 0)
146 size = 0;
148 return size;
149 }
151 static int
152 acpi_system_write_debug(struct file *file,
153 const char __user * buffer,
154 unsigned long count, void *data)
155 {
156 char debug_string[12] = { '\0' };
159 if (count > sizeof(debug_string) - 1)
160 return -EINVAL;
162 if (copy_from_user(debug_string, buffer, count))
163 return -EFAULT;
165 debug_string[count] = '\0';
167 switch ((unsigned long)data) {
168 case 0:
169 acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0);
170 break;
171 case 1:
172 acpi_dbg_level = simple_strtoul(debug_string, NULL, 0);
173 break;
174 default:
175 return -EINVAL;
176 }
178 return count;
179 }
181 static int __init acpi_debug_init(void)
182 {
183 struct proc_dir_entry *entry;
184 int error = 0;
185 char *name;
188 if (acpi_disabled)
189 return 0;
191 /* 'debug_layer' [R/W] */
192 name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
193 entry =
194 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
195 acpi_root_dir, acpi_system_read_debug,
196 (void *)0);
197 if (entry)
198 entry->write_proc = acpi_system_write_debug;
199 else
200 goto Error;
202 /* 'debug_level' [R/W] */
203 name = ACPI_SYSTEM_FILE_DEBUG_LEVEL;
204 entry =
205 create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
206 acpi_root_dir, acpi_system_read_debug,
207 (void *)1);
208 if (entry)
209 entry->write_proc = acpi_system_write_debug;
210 else
211 goto Error;
213 Done:
214 return error;
216 Error:
217 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir);
218 remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
219 error = -ENODEV;
220 goto Done;
221 }
223 subsys_initcall(acpi_debug_init);