ia64/linux-2.6.18-xen.hg

view drivers/net/gianfar_sysfs.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 * drivers/net/gianfar_sysfs.c
3 *
4 * Gianfar Ethernet Driver
5 * This driver is designed for the non-CPM ethernet controllers
6 * on the 85xx and 83xx family of integrated processors
7 * Based on 8260_io/fcc_enet.c
8 *
9 * Author: Andy Fleming
10 * Maintainer: Kumar Gala (galak@kernel.crashing.org)
11 *
12 * Copyright (c) 2002-2005 Freescale Semiconductor, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 *
19 * Sysfs file creation and management
20 */
22 #include <linux/kernel.h>
23 #include <linux/sched.h>
24 #include <linux/string.h>
25 #include <linux/errno.h>
26 #include <linux/unistd.h>
27 #include <linux/slab.h>
28 #include <linux/init.h>
29 #include <linux/delay.h>
30 #include <linux/etherdevice.h>
31 #include <linux/spinlock.h>
32 #include <linux/mm.h>
33 #include <linux/device.h>
35 #include <asm/uaccess.h>
36 #include <linux/module.h>
37 #include <linux/version.h>
39 #include "gianfar.h"
41 #define GFAR_ATTR(_name) \
42 static ssize_t gfar_show_##_name(struct class_device *cdev, char *buf); \
43 static ssize_t gfar_set_##_name(struct class_device *cdev, \
44 const char *buf, size_t count); \
45 static CLASS_DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
47 #define GFAR_CREATE_FILE(_dev, _name) \
48 class_device_create_file(&_dev->class_dev, &class_device_attr_##_name)
50 GFAR_ATTR(bd_stash);
51 GFAR_ATTR(rx_stash_size);
52 GFAR_ATTR(rx_stash_index);
53 GFAR_ATTR(fifo_threshold);
54 GFAR_ATTR(fifo_starve);
55 GFAR_ATTR(fifo_starve_off);
57 #define to_net_dev(cd) container_of(cd, struct net_device, class_dev)
59 static ssize_t gfar_show_bd_stash(struct class_device *cdev, char *buf)
60 {
61 struct net_device *dev = to_net_dev(cdev);
62 struct gfar_private *priv = netdev_priv(dev);
64 return sprintf(buf, "%s\n", priv->bd_stash_en? "on" : "off");
65 }
67 static ssize_t gfar_set_bd_stash(struct class_device *cdev,
68 const char *buf, size_t count)
69 {
70 struct net_device *dev = to_net_dev(cdev);
71 struct gfar_private *priv = netdev_priv(dev);
72 int new_setting = 0;
73 u32 temp;
74 unsigned long flags;
76 /* Find out the new setting */
77 if (!strncmp("on", buf, count-1) || !strncmp("1", buf, count-1))
78 new_setting = 1;
79 else if (!strncmp("off", buf, count-1) || !strncmp("0", buf, count-1))
80 new_setting = 0;
81 else
82 return count;
84 spin_lock_irqsave(&priv->rxlock, flags);
86 /* Set the new stashing value */
87 priv->bd_stash_en = new_setting;
89 temp = gfar_read(&priv->regs->attr);
91 if (new_setting)
92 temp |= ATTR_BDSTASH;
93 else
94 temp &= ~(ATTR_BDSTASH);
96 gfar_write(&priv->regs->attr, temp);
98 spin_unlock_irqrestore(&priv->rxlock, flags);
100 return count;
101 }
103 static ssize_t gfar_show_rx_stash_size(struct class_device *cdev, char *buf)
104 {
105 struct net_device *dev = to_net_dev(cdev);
106 struct gfar_private *priv = netdev_priv(dev);
108 return sprintf(buf, "%d\n", priv->rx_stash_size);
109 }
111 static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
112 const char *buf, size_t count)
113 {
114 struct net_device *dev = to_net_dev(cdev);
115 struct gfar_private *priv = netdev_priv(dev);
116 unsigned int length = simple_strtoul(buf, NULL, 0);
117 u32 temp;
118 unsigned long flags;
120 spin_lock_irqsave(&priv->rxlock, flags);
121 if (length > priv->rx_buffer_size)
122 return count;
124 if (length == priv->rx_stash_size)
125 return count;
127 priv->rx_stash_size = length;
129 temp = gfar_read(&priv->regs->attreli);
130 temp &= ~ATTRELI_EL_MASK;
131 temp |= ATTRELI_EL(length);
132 gfar_write(&priv->regs->attreli, temp);
134 /* Turn stashing on/off as appropriate */
135 temp = gfar_read(&priv->regs->attr);
137 if (length)
138 temp |= ATTR_BUFSTASH;
139 else
140 temp &= ~(ATTR_BUFSTASH);
142 gfar_write(&priv->regs->attr, temp);
144 spin_unlock_irqrestore(&priv->rxlock, flags);
146 return count;
147 }
150 /* Stashing will only be enabled when rx_stash_size != 0 */
151 static ssize_t gfar_show_rx_stash_index(struct class_device *cdev, char *buf)
152 {
153 struct net_device *dev = to_net_dev(cdev);
154 struct gfar_private *priv = netdev_priv(dev);
156 return sprintf(buf, "%d\n", priv->rx_stash_index);
157 }
159 static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
160 const char *buf, size_t count)
161 {
162 struct net_device *dev = to_net_dev(cdev);
163 struct gfar_private *priv = netdev_priv(dev);
164 unsigned short index = simple_strtoul(buf, NULL, 0);
165 u32 temp;
166 unsigned long flags;
168 spin_lock_irqsave(&priv->rxlock, flags);
169 if (index > priv->rx_stash_size)
170 return count;
172 if (index == priv->rx_stash_index)
173 return count;
175 priv->rx_stash_index = index;
177 temp = gfar_read(&priv->regs->attreli);
178 temp &= ~ATTRELI_EI_MASK;
179 temp |= ATTRELI_EI(index);
180 gfar_write(&priv->regs->attreli, flags);
182 spin_unlock_irqrestore(&priv->rxlock, flags);
184 return count;
185 }
187 static ssize_t gfar_show_fifo_threshold(struct class_device *cdev, char *buf)
188 {
189 struct net_device *dev = to_net_dev(cdev);
190 struct gfar_private *priv = netdev_priv(dev);
192 return sprintf(buf, "%d\n", priv->fifo_threshold);
193 }
195 static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
196 const char *buf, size_t count)
197 {
198 struct net_device *dev = to_net_dev(cdev);
199 struct gfar_private *priv = netdev_priv(dev);
200 unsigned int length = simple_strtoul(buf, NULL, 0);
201 u32 temp;
202 unsigned long flags;
204 if (length > GFAR_MAX_FIFO_THRESHOLD)
205 return count;
207 spin_lock_irqsave(&priv->txlock, flags);
209 priv->fifo_threshold = length;
211 temp = gfar_read(&priv->regs->fifo_tx_thr);
212 temp &= ~FIFO_TX_THR_MASK;
213 temp |= length;
214 gfar_write(&priv->regs->fifo_tx_thr, temp);
216 spin_unlock_irqrestore(&priv->txlock, flags);
218 return count;
219 }
221 static ssize_t gfar_show_fifo_starve(struct class_device *cdev, char *buf)
222 {
223 struct net_device *dev = to_net_dev(cdev);
224 struct gfar_private *priv = netdev_priv(dev);
226 return sprintf(buf, "%d\n", priv->fifo_starve);
227 }
230 static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
231 const char *buf, size_t count)
232 {
233 struct net_device *dev = to_net_dev(cdev);
234 struct gfar_private *priv = netdev_priv(dev);
235 unsigned int num = simple_strtoul(buf, NULL, 0);
236 u32 temp;
237 unsigned long flags;
239 if (num > GFAR_MAX_FIFO_STARVE)
240 return count;
242 spin_lock_irqsave(&priv->txlock, flags);
244 priv->fifo_starve = num;
246 temp = gfar_read(&priv->regs->fifo_tx_starve);
247 temp &= ~FIFO_TX_STARVE_MASK;
248 temp |= num;
249 gfar_write(&priv->regs->fifo_tx_starve, temp);
251 spin_unlock_irqrestore(&priv->txlock, flags);
253 return count;
254 }
256 static ssize_t gfar_show_fifo_starve_off(struct class_device *cdev, char *buf)
257 {
258 struct net_device *dev = to_net_dev(cdev);
259 struct gfar_private *priv = netdev_priv(dev);
261 return sprintf(buf, "%d\n", priv->fifo_starve_off);
262 }
264 static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
265 const char *buf, size_t count)
266 {
267 struct net_device *dev = to_net_dev(cdev);
268 struct gfar_private *priv = netdev_priv(dev);
269 unsigned int num = simple_strtoul(buf, NULL, 0);
270 u32 temp;
271 unsigned long flags;
273 if (num > GFAR_MAX_FIFO_STARVE_OFF)
274 return count;
276 spin_lock_irqsave(&priv->txlock, flags);
278 priv->fifo_starve_off = num;
280 temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
281 temp &= ~FIFO_TX_STARVE_OFF_MASK;
282 temp |= num;
283 gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);
285 spin_unlock_irqrestore(&priv->txlock, flags);
287 return count;
288 }
290 void gfar_init_sysfs(struct net_device *dev)
291 {
292 struct gfar_private *priv = netdev_priv(dev);
294 /* Initialize the default values */
295 priv->rx_stash_size = DEFAULT_STASH_LENGTH;
296 priv->rx_stash_index = DEFAULT_STASH_INDEX;
297 priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
298 priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
299 priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
300 priv->bd_stash_en = DEFAULT_BD_STASH;
302 /* Create our sysfs files */
303 GFAR_CREATE_FILE(dev, bd_stash);
304 GFAR_CREATE_FILE(dev, rx_stash_size);
305 GFAR_CREATE_FILE(dev, rx_stash_index);
306 GFAR_CREATE_FILE(dev, fifo_threshold);
307 GFAR_CREATE_FILE(dev, fifo_starve);
308 GFAR_CREATE_FILE(dev, fifo_starve_off);
310 }