ia64/linux-2.6.18-xen.hg

view arch/mips/basler/excite/excite_flashtest.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 * Copyright (C) 2005 by Basler Vision Technologies AG
3 * Author: Thies Moeller <thies.moeller@baslerweb.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
20 #include <linux/module.h>
21 #include <linux/types.h>
22 #include <linux/init.h>
23 #include <linux/kernel.h>
24 #include <linux/string.h>
25 #include <linux/ioport.h>
26 #include <linux/device.h>
27 #include <linux/delay.h>
28 #include <linux/err.h>
29 #include <linux/kernel.h>
31 #include <excite.h>
33 #include <asm/io.h>
35 #include <linux/mtd/mtd.h>
36 #include <linux/mtd/nand.h>
37 #include <linux/mtd/nand_ecc.h>
38 #include <linux/mtd/partitions.h>
39 #include <asm/rm9k-ocd.h> // for ocd_write
40 #include <linux/workqueue.h> // for queue
42 #include "excite_nandflash.h"
43 #include "nandflash.h"
45 #define PFX "excite flashtest: "
46 typedef void __iomem *io_reg_t;
48 #define io_readb(__a__) __raw_readb((__a__))
49 #define io_writeb(__v__, __a__) __raw_writeb((__v__), (__a__))
53 static inline const struct resource *excite_nandflash_get_resource(
54 struct platform_device *d, unsigned long flags, const char *basename)
55 {
56 const char fmt[] = "%s_%u";
57 char buf[80];
59 if (unlikely(snprintf(buf, sizeof buf, fmt, basename, d->id) >= sizeof buf))
60 return NULL;
62 return platform_get_resource_byname(d, flags, buf);
63 }
65 static inline io_reg_t
66 excite_nandflash_map_regs(struct platform_device *d, const char *basename)
67 {
68 void *result = NULL;
69 const struct resource *const r =
70 excite_nandflash_get_resource(d, IORESOURCE_MEM, basename);
71 if (r)
72 result = ioremap_nocache(r->start, r->end + 1 - r->start);
73 return result;
74 }
76 /* controller and mtd information */
78 struct excite_nandflash_drvdata {
79 struct mtd_info board_mtd;
80 struct nand_chip board_chip;
81 io_reg_t regs;
82 };
85 /* command and control functions */
86 static void excite_nandflash_hwcontrol(struct mtd_info *mtd, int cmd)
87 {
88 struct nand_chip *this = mtd->priv;
89 io_reg_t regs = container_of(mtd,struct excite_nandflash_drvdata,board_mtd)->regs;
91 switch (cmd) {
92 /* Select the command latch */
93 case NAND_CTL_SETCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_CMD;
94 break;
95 /* Deselect the command latch */
96 case NAND_CTL_CLRCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA;
97 break;
98 /* Select the address latch */
99 case NAND_CTL_SETALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_ADDR;
100 break;
101 /* Deselect the address latch */
102 case NAND_CTL_CLRALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA;
103 break;
104 /* Select the chip -- not used */
105 case NAND_CTL_SETNCE:
106 break;
107 /* Deselect the chip -- not used */
108 case NAND_CTL_CLRNCE:
109 break;
110 }
112 this->IO_ADDR_R = this->IO_ADDR_W;
113 }
115 /* excite_nandflash_devready()
116 *
117 * returns 0 if the nand is busy, 1 if it is ready
118 */
119 static int excite_nandflash_devready(struct mtd_info *mtd)
120 {
121 struct excite_nandflash_drvdata *drvdata =
122 container_of(mtd, struct excite_nandflash_drvdata, board_mtd);
124 return io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
125 }
127 /* device management functions */
129 /* excite_nandflash_remove
130 *
131 * called by device layer to remove the driver
132 * the binding to the mtd and all allocated
133 * resources are released
134 */
135 static int excite_nandflash_remove(struct device *dev)
136 {
137 struct excite_nandflash_drvdata *this = dev_get_drvdata(dev);
139 pr_info(PFX "remove");
141 dev_set_drvdata(dev, NULL);
143 if (this == NULL) {
144 pr_debug(PFX "call remove without private data!!");
145 return 0;
146 }
149 /* free the common resources */
150 if (this->regs != NULL) {
151 iounmap(this->regs);
152 this->regs = NULL;
153 }
155 kfree(this);
157 return 0;
158 }
160 static int elapsed;
162 void my_workqueue_handler(void *arg)
163 {
164 elapsed = 1;
165 }
167 DECLARE_WORK(sigElapsed, my_workqueue_handler, 0);
170 /* excite_nandflash_probe
171 *
172 * called by device layer when it finds a device matching
173 * one our driver can handled. This code checks to see if
174 * it can allocate all necessary resources then calls the
175 * nand layer to look for devices
176 */
177 static int excite_nandflash_probe(struct device *dev)
178 {
179 struct platform_device *pdev = to_platform_device(dev);
181 struct excite_nandflash_drvdata *drvdata; /* private driver data */
182 struct nand_chip *board_chip; /* private flash chip data */
183 struct mtd_info *board_mtd; /* mtd info for this board */
185 int err = 0;
186 int count = 0;
187 struct timeval tv,endtv;
188 unsigned int dt;
190 pr_info(PFX "probe dev: (%p)\n", dev);
192 pr_info(PFX "adjust LB timing\n");
193 ocd_writel(0x00000330, LDP2);
195 drvdata = kmalloc(sizeof(*drvdata), GFP_KERNEL);
196 if (unlikely(!drvdata)) {
197 printk(KERN_ERR PFX "no memory for drvdata\n");
198 err = -ENOMEM;
199 goto mem_error;
200 }
202 /* Initialize structures */
203 memset(drvdata, 0, sizeof(*drvdata));
205 /* bind private data into driver */
206 dev_set_drvdata(dev, drvdata);
208 /* allocate and map the resource */
209 drvdata->regs =
210 excite_nandflash_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);
212 if (unlikely(!drvdata->regs)) {
213 printk(KERN_ERR PFX "cannot reserve register region\n");
214 err = -ENXIO;
215 goto io_error;
216 }
218 /* initialise our chip */
219 board_chip = &drvdata->board_chip;
221 board_chip->IO_ADDR_R = drvdata->regs + EXCITE_NANDFLASH_DATA;
222 board_chip->IO_ADDR_W = drvdata->regs + EXCITE_NANDFLASH_DATA;
224 board_chip->hwcontrol = excite_nandflash_hwcontrol;
225 board_chip->dev_ready = excite_nandflash_devready;
227 board_chip->chip_delay = 25;
228 #if 0
229 /* TODO: speedup the initial scan */
230 board_chip->options = NAND_USE_FLASH_BBT;
231 #endif
232 board_chip->eccmode = NAND_ECC_SOFT;
234 /* link chip to mtd */
235 board_mtd = &drvdata->board_mtd;
236 board_mtd->priv = board_chip;
239 pr_info(PFX "FlashTest\n");
240 elapsed = 0;
241 /* schedule_delayed_work(&sigElapsed, 1*HZ);
242 while (!elapsed) {
243 io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
244 count++;
245 }
246 pr_info(PFX "reads in 1 sec --> %d\n",count);
247 */
248 do_gettimeofday(&tv);
249 for (count = 0 ; count < 1000000; count ++) {
250 io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS);
251 }
252 do_gettimeofday(&endtv);
253 dt = (endtv.tv_sec - tv.tv_sec) * 1000000 + endtv.tv_usec - tv.tv_usec;
254 pr_info(PFX "%8d us timeval\n",dt);
255 pr_info(PFX "EndFlashTest\n");
257 /* return with error to unload everything
258 */
259 io_error:
260 iounmap(drvdata->regs);
262 mem_error:
263 kfree(drvdata);
265 if (err == 0)
266 err = -EINVAL;
267 return err;
268 }
270 static struct device_driver excite_nandflash_driver = {
271 .name = "excite_nand",
272 .bus = &platform_bus_type,
273 .probe = excite_nandflash_probe,
274 .remove = excite_nandflash_remove,
275 };
277 static int __init excite_nandflash_init(void)
278 {
279 pr_info(PFX "register Driver (Rev: $Revision:$)\n");
280 return driver_register(&excite_nandflash_driver);
281 }
283 static void __exit excite_nandflash_exit(void)
284 {
285 driver_unregister(&excite_nandflash_driver);
286 pr_info(PFX "Driver unregistered");
287 }
289 module_init(excite_nandflash_init);
290 module_exit(excite_nandflash_exit);
292 MODULE_AUTHOR("Thies Moeller <thies.moeller@baslerweb.com>");
293 MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
294 MODULE_LICENSE("GPL");