ia64/linux-2.6.18-xen.hg

view drivers/net/gianfar_mii.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_mii.c
3 *
4 * Gianfar Ethernet Driver -- MIIM bus implementation
5 * Provides Bus interface for MIIM regs
6 *
7 * Author: Andy Fleming
8 * Maintainer: Kumar Gala
9 *
10 * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 */
19 #include <linux/kernel.h>
20 #include <linux/sched.h>
21 #include <linux/string.h>
22 #include <linux/errno.h>
23 #include <linux/unistd.h>
24 #include <linux/slab.h>
25 #include <linux/interrupt.h>
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/netdevice.h>
29 #include <linux/etherdevice.h>
30 #include <linux/skbuff.h>
31 #include <linux/spinlock.h>
32 #include <linux/mm.h>
33 #include <linux/module.h>
34 #include <linux/platform_device.h>
35 #include <asm/ocp.h>
36 #include <linux/crc32.h>
37 #include <linux/mii.h>
38 #include <linux/phy.h>
40 #include <asm/io.h>
41 #include <asm/irq.h>
42 #include <asm/uaccess.h>
44 #include "gianfar.h"
45 #include "gianfar_mii.h"
47 /* Write value to the PHY at mii_id at register regnum,
48 * on the bus, waiting until the write is done before returning.
49 * All PHY configuration is done through the TSEC1 MIIM regs */
50 int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
51 {
52 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
54 /* Set the PHY address and the register address we want to write */
55 gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
57 /* Write out the value we want */
58 gfar_write(&regs->miimcon, value);
60 /* Wait for the transaction to finish */
61 while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
62 cpu_relax();
64 return 0;
65 }
67 /* Read the bus for PHY at addr mii_id, register regnum, and
68 * return the value. Clears miimcom first. All PHY
69 * configuration has to be done through the TSEC1 MIIM regs */
70 int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
71 {
72 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
73 u16 value;
75 /* Set the PHY address and the register address we want to read */
76 gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
78 /* Clear miimcom, and then initiate a read */
79 gfar_write(&regs->miimcom, 0);
80 gfar_write(&regs->miimcom, MII_READ_COMMAND);
82 /* Wait for the transaction to finish */
83 while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
84 cpu_relax();
86 /* Grab the value of the register from miimstat */
87 value = gfar_read(&regs->miimstat);
89 return value;
90 }
93 /* Reset the MIIM registers, and wait for the bus to free */
94 int gfar_mdio_reset(struct mii_bus *bus)
95 {
96 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
97 unsigned int timeout = PHY_INIT_TIMEOUT;
99 spin_lock_bh(&bus->mdio_lock);
101 /* Reset the management interface */
102 gfar_write(&regs->miimcfg, MIIMCFG_RESET);
104 /* Setup the MII Mgmt clock speed */
105 gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);
107 /* Wait until the bus is free */
108 while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
109 timeout--)
110 cpu_relax();
112 spin_unlock_bh(&bus->mdio_lock);
114 if(timeout <= 0) {
115 printk(KERN_ERR "%s: The MII Bus is stuck!\n",
116 bus->name);
117 return -EBUSY;
118 }
120 return 0;
121 }
124 int gfar_mdio_probe(struct device *dev)
125 {
126 struct platform_device *pdev = to_platform_device(dev);
127 struct gianfar_mdio_data *pdata;
128 struct gfar_mii __iomem *regs;
129 struct mii_bus *new_bus;
130 struct resource *r;
131 int err = 0;
133 if (NULL == dev)
134 return -EINVAL;
136 new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
138 if (NULL == new_bus)
139 return -ENOMEM;
141 new_bus->name = "Gianfar MII Bus",
142 new_bus->read = &gfar_mdio_read,
143 new_bus->write = &gfar_mdio_write,
144 new_bus->reset = &gfar_mdio_reset,
145 new_bus->id = pdev->id;
147 pdata = (struct gianfar_mdio_data *)pdev->dev.platform_data;
149 if (NULL == pdata) {
150 printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
151 return -ENODEV;
152 }
154 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
156 /* Set the PHY base address */
157 regs = ioremap(r->start, sizeof (struct gfar_mii));
159 if (NULL == regs) {
160 err = -ENOMEM;
161 goto reg_map_fail;
162 }
164 new_bus->priv = (void __force *)regs;
166 new_bus->irq = pdata->irq;
168 new_bus->dev = dev;
169 dev_set_drvdata(dev, new_bus);
171 err = mdiobus_register(new_bus);
173 if (0 != err) {
174 printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
175 new_bus->name);
176 goto bus_register_fail;
177 }
179 return 0;
181 bus_register_fail:
182 iounmap(regs);
183 reg_map_fail:
184 kfree(new_bus);
186 return err;
187 }
190 int gfar_mdio_remove(struct device *dev)
191 {
192 struct mii_bus *bus = dev_get_drvdata(dev);
194 mdiobus_unregister(bus);
196 dev_set_drvdata(dev, NULL);
198 iounmap((void __iomem *)bus->priv);
199 bus->priv = NULL;
200 kfree(bus);
202 return 0;
203 }
205 static struct device_driver gianfar_mdio_driver = {
206 .name = "fsl-gianfar_mdio",
207 .bus = &platform_bus_type,
208 .probe = gfar_mdio_probe,
209 .remove = gfar_mdio_remove,
210 };
212 int __init gfar_mdio_init(void)
213 {
214 return driver_register(&gianfar_mdio_driver);
215 }
217 void __exit gfar_mdio_exit(void)
218 {
219 driver_unregister(&gianfar_mdio_driver);
220 }