ia64/linux-2.6.18-xen.hg

view drivers/telephony/phonedev.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 * Telephony registration for Linux
3 *
4 * (c) Copyright 1999 Red Hat Software Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * Author: Alan Cox, <alan@redhat.com>
12 *
13 * Fixes: Mar 01 2000 Thomas Sparr, <thomas.l.sparr@telia.com>
14 * phone_register_device now works with unit!=PHONE_UNIT_ANY
15 */
17 #include <linux/module.h>
18 #include <linux/types.h>
19 #include <linux/kernel.h>
20 #include <linux/fs.h>
21 #include <linux/mm.h>
22 #include <linux/string.h>
23 #include <linux/errno.h>
24 #include <linux/phonedev.h>
25 #include <linux/init.h>
26 #include <asm/uaccess.h>
27 #include <asm/system.h>
29 #include <linux/kmod.h>
30 #include <linux/sem.h>
31 #include <linux/mutex.h>
33 #define PHONE_NUM_DEVICES 256
35 /*
36 * Active devices
37 */
39 static struct phone_device *phone_device[PHONE_NUM_DEVICES];
40 static DEFINE_MUTEX(phone_lock);
42 /*
43 * Open a phone device.
44 */
46 static int phone_open(struct inode *inode, struct file *file)
47 {
48 unsigned int minor = iminor(inode);
49 int err = 0;
50 struct phone_device *p;
51 const struct file_operations *old_fops, *new_fops = NULL;
53 if (minor >= PHONE_NUM_DEVICES)
54 return -ENODEV;
56 mutex_lock(&phone_lock);
57 p = phone_device[minor];
58 if (p)
59 new_fops = fops_get(p->f_op);
60 if (!new_fops) {
61 mutex_unlock(&phone_lock);
62 request_module("char-major-%d-%d", PHONE_MAJOR, minor);
63 mutex_lock(&phone_lock);
64 p = phone_device[minor];
65 if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL)
66 {
67 err=-ENODEV;
68 goto end;
69 }
70 }
71 old_fops = file->f_op;
72 file->f_op = new_fops;
73 if (p->open)
74 err = p->open(p, file); /* Tell the device it is open */
75 if (err) {
76 fops_put(file->f_op);
77 file->f_op = fops_get(old_fops);
78 }
79 fops_put(old_fops);
80 end:
81 mutex_unlock(&phone_lock);
82 return err;
83 }
85 /*
86 * Telephony For Linux device drivers request registration here.
87 */
89 int phone_register_device(struct phone_device *p, int unit)
90 {
91 int base;
92 int end;
93 int i;
95 base = 0;
96 end = PHONE_NUM_DEVICES - 1;
98 if (unit != PHONE_UNIT_ANY) {
99 base = unit;
100 end = unit + 1; /* enter the loop at least one time */
101 }
103 mutex_lock(&phone_lock);
104 for (i = base; i < end; i++) {
105 if (phone_device[i] == NULL) {
106 phone_device[i] = p;
107 p->minor = i;
108 mutex_unlock(&phone_lock);
109 return 0;
110 }
111 }
112 mutex_unlock(&phone_lock);
113 return -ENFILE;
114 }
116 /*
117 * Unregister an unused Telephony for linux device
118 */
120 void phone_unregister_device(struct phone_device *pfd)
121 {
122 mutex_lock(&phone_lock);
123 if (phone_device[pfd->minor] != pfd)
124 panic("phone: bad unregister");
125 phone_device[pfd->minor] = NULL;
126 mutex_unlock(&phone_lock);
127 }
130 static struct file_operations phone_fops =
131 {
132 .owner = THIS_MODULE,
133 .open = phone_open,
134 };
136 /*
137 * Board init functions
138 */
141 /*
142 * Initialise Telephony for linux
143 */
145 static int __init telephony_init(void)
146 {
147 printk(KERN_INFO "Linux telephony interface: v1.00\n");
148 if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) {
149 printk("phonedev: unable to get major %d\n", PHONE_MAJOR);
150 return -EIO;
151 }
153 return 0;
154 }
156 static void __exit telephony_exit(void)
157 {
158 unregister_chrdev(PHONE_MAJOR, "telephony");
159 }
161 module_init(telephony_init);
162 module_exit(telephony_exit);
164 MODULE_LICENSE("GPL");
166 EXPORT_SYMBOL(phone_register_device);
167 EXPORT_SYMBOL(phone_unregister_device);