ia64/linux-2.6.18-xen.hg

view drivers/acpi/system.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_system.c - ACPI System Driver ($Revision: 63 $)
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 #include <linux/proc_fs.h>
27 #include <linux/seq_file.h>
28 #include <linux/init.h>
29 #include <asm/uaccess.h>
31 #include <acpi/acpi_drivers.h>
33 #define _COMPONENT ACPI_SYSTEM_COMPONENT
34 ACPI_MODULE_NAME("acpi_system")
35 #define ACPI_SYSTEM_CLASS "system"
36 #define ACPI_SYSTEM_DRIVER_NAME "ACPI System Driver"
37 #define ACPI_SYSTEM_DEVICE_NAME "System"
38 #define ACPI_SYSTEM_FILE_INFO "info"
39 #define ACPI_SYSTEM_FILE_EVENT "event"
40 #define ACPI_SYSTEM_FILE_DSDT "dsdt"
41 #define ACPI_SYSTEM_FILE_FADT "fadt"
42 extern struct fadt_descriptor acpi_fadt;
44 /* --------------------------------------------------------------------------
45 FS Interface (/proc)
46 -------------------------------------------------------------------------- */
48 static int acpi_system_read_info(struct seq_file *seq, void *offset)
49 {
51 seq_printf(seq, "version: %x\n", ACPI_CA_VERSION);
52 return 0;
53 }
55 static int acpi_system_info_open_fs(struct inode *inode, struct file *file)
56 {
57 return single_open(file, acpi_system_read_info, PDE(inode)->data);
58 }
60 static const struct file_operations acpi_system_info_ops = {
61 .open = acpi_system_info_open_fs,
62 .read = seq_read,
63 .llseek = seq_lseek,
64 .release = single_release,
65 };
67 static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
68 loff_t *);
70 static const struct file_operations acpi_system_dsdt_ops = {
71 .read = acpi_system_read_dsdt,
72 };
74 static ssize_t
75 acpi_system_read_dsdt(struct file *file,
76 char __user * buffer, size_t count, loff_t * ppos)
77 {
78 acpi_status status = AE_OK;
79 struct acpi_buffer dsdt = { ACPI_ALLOCATE_BUFFER, NULL };
80 ssize_t res;
83 status = acpi_get_table(ACPI_TABLE_ID_DSDT, 1, &dsdt);
84 if (ACPI_FAILURE(status))
85 return -ENODEV;
87 res = simple_read_from_buffer(buffer, count, ppos,
88 dsdt.pointer, dsdt.length);
89 kfree(dsdt.pointer);
91 return res;
92 }
94 static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
95 loff_t *);
97 static const struct file_operations acpi_system_fadt_ops = {
98 .read = acpi_system_read_fadt,
99 };
101 static ssize_t
102 acpi_system_read_fadt(struct file *file,
103 char __user * buffer, size_t count, loff_t * ppos)
104 {
105 acpi_status status = AE_OK;
106 struct acpi_buffer fadt = { ACPI_ALLOCATE_BUFFER, NULL };
107 ssize_t res;
110 status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &fadt);
111 if (ACPI_FAILURE(status))
112 return -ENODEV;
114 res = simple_read_from_buffer(buffer, count, ppos,
115 fadt.pointer, fadt.length);
116 kfree(fadt.pointer);
118 return res;
119 }
121 static int __init acpi_system_init(void)
122 {
123 struct proc_dir_entry *entry;
124 int error = 0;
125 char *name;
128 if (acpi_disabled)
129 return 0;
131 /* 'info' [R] */
132 name = ACPI_SYSTEM_FILE_INFO;
133 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
134 if (!entry)
135 goto Error;
136 else {
137 entry->proc_fops = &acpi_system_info_ops;
138 }
140 /* 'dsdt' [R] */
141 name = ACPI_SYSTEM_FILE_DSDT;
142 entry = create_proc_entry(name, S_IRUSR, acpi_root_dir);
143 if (entry)
144 entry->proc_fops = &acpi_system_dsdt_ops;
145 else
146 goto Error;
148 /* 'fadt' [R] */
149 name = ACPI_SYSTEM_FILE_FADT;
150 entry = create_proc_entry(name, S_IRUSR, acpi_root_dir);
151 if (entry)
152 entry->proc_fops = &acpi_system_fadt_ops;
153 else
154 goto Error;
156 Done:
157 return error;
159 Error:
160 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
161 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
162 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
164 error = -EFAULT;
165 goto Done;
166 }
168 subsys_initcall(acpi_system_init);