ia64/linux-2.6.18-xen.hg

view drivers/net/pppox.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 /** -*- linux-c -*- ***********************************************************
2 * Linux PPP over X/Ethernet (PPPoX/PPPoE) Sockets
3 *
4 * PPPoX --- Generic PPP encapsulation socket family
5 * PPPoE --- PPP over Ethernet (RFC 2516)
6 *
7 *
8 * Version: 0.5.2
9 *
10 * Author: Michal Ostrowski <mostrows@speakeasy.net>
11 *
12 * 051000 : Initialization cleanup
13 *
14 * License:
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
19 *
20 */
22 #include <linux/string.h>
23 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/slab.h>
26 #include <linux/errno.h>
27 #include <linux/netdevice.h>
28 #include <linux/net.h>
29 #include <linux/init.h>
30 #include <linux/if_pppox.h>
31 #include <linux/ppp_defs.h>
32 #include <linux/if_ppp.h>
33 #include <linux/ppp_channel.h>
35 #include <net/sock.h>
37 #include <asm/uaccess.h>
39 static struct pppox_proto *pppox_protos[PX_MAX_PROTO + 1];
41 int register_pppox_proto(int proto_num, struct pppox_proto *pp)
42 {
43 if (proto_num < 0 || proto_num > PX_MAX_PROTO)
44 return -EINVAL;
45 if (pppox_protos[proto_num])
46 return -EALREADY;
47 pppox_protos[proto_num] = pp;
48 return 0;
49 }
51 void unregister_pppox_proto(int proto_num)
52 {
53 if (proto_num >= 0 && proto_num <= PX_MAX_PROTO)
54 pppox_protos[proto_num] = NULL;
55 }
57 void pppox_unbind_sock(struct sock *sk)
58 {
59 /* Clear connection to ppp device, if attached. */
61 if (sk->sk_state & (PPPOX_BOUND | PPPOX_ZOMBIE)) {
62 ppp_unregister_channel(&pppox_sk(sk)->chan);
63 sk->sk_state = PPPOX_DEAD;
64 }
65 }
67 EXPORT_SYMBOL(register_pppox_proto);
68 EXPORT_SYMBOL(unregister_pppox_proto);
69 EXPORT_SYMBOL(pppox_unbind_sock);
71 int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
72 {
73 struct sock *sk = sock->sk;
74 struct pppox_sock *po = pppox_sk(sk);
75 int rc = 0;
77 lock_sock(sk);
79 switch (cmd) {
80 case PPPIOCGCHAN: {
81 int index;
82 rc = -ENOTCONN;
83 if (!(sk->sk_state & PPPOX_CONNECTED))
84 break;
86 rc = -EINVAL;
87 index = ppp_channel_index(&po->chan);
88 if (put_user(index , (int __user *) arg))
89 break;
91 rc = 0;
92 sk->sk_state |= PPPOX_BOUND;
93 break;
94 }
95 default:
96 if (pppox_protos[sk->sk_protocol]->ioctl)
97 rc = pppox_protos[sk->sk_protocol]->ioctl(sock, cmd,
98 arg);
100 break;
101 };
103 release_sock(sk);
104 return rc;
105 }
107 EXPORT_SYMBOL(pppox_ioctl);
109 static int pppox_create(struct socket *sock, int protocol)
110 {
111 int rc = -EPROTOTYPE;
113 if (protocol < 0 || protocol > PX_MAX_PROTO)
114 goto out;
116 rc = -EPROTONOSUPPORT;
117 if (!pppox_protos[protocol] ||
118 !try_module_get(pppox_protos[protocol]->owner))
119 goto out;
121 rc = pppox_protos[protocol]->create(sock);
123 module_put(pppox_protos[protocol]->owner);
124 out:
125 return rc;
126 }
128 static struct net_proto_family pppox_proto_family = {
129 .family = PF_PPPOX,
130 .create = pppox_create,
131 .owner = THIS_MODULE,
132 };
134 static int __init pppox_init(void)
135 {
136 return sock_register(&pppox_proto_family);
137 }
139 static void __exit pppox_exit(void)
140 {
141 sock_unregister(PF_PPPOX);
142 }
144 module_init(pppox_init);
145 module_exit(pppox_exit);
147 MODULE_AUTHOR("Michal Ostrowski <mostrows@speakeasy.net>");
148 MODULE_DESCRIPTION("PPP over Ethernet driver (generic socket layer)");
149 MODULE_LICENSE("GPL");