ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/bast-flash.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/drivers/mtd/maps/bast_flash.c
2 *
3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Simtec Bast (EB2410ITX) NOR MTD Mapping driver
7 *
8 * Changelog:
9 * 20-Sep-2004 BJD Initial version
10 * 17-Jan-2005 BJD Add whole device if no partitions found
11 *
12 * $Id: bast-flash.c,v 1.5 2005/11/07 11:14:26 gleixner Exp $
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */
29 #include <linux/module.h>
30 #include <linux/types.h>
31 #include <linux/init.h>
32 #include <linux/kernel.h>
33 #include <linux/string.h>
34 #include <linux/ioport.h>
35 #include <linux/device.h>
36 #include <linux/slab.h>
37 #include <linux/platform_device.h>
38 #include <linux/mtd/mtd.h>
39 #include <linux/mtd/map.h>
40 #include <linux/mtd/partitions.h>
42 #include <asm/io.h>
43 #include <asm/mach/flash.h>
45 #include <asm/arch/map.h>
46 #include <asm/arch/bast-map.h>
47 #include <asm/arch/bast-cpld.h>
49 #ifdef CONFIG_MTD_BAST_MAXSIZE
50 #define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * SZ_1M)
51 #else
52 #define AREA_MAXSIZE (32 * SZ_1M)
53 #endif
55 #define PFX "bast-flash: "
57 struct bast_flash_info {
58 struct mtd_info *mtd;
59 struct map_info map;
60 struct mtd_partition *partitions;
61 struct resource *area;
62 };
64 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
66 static void bast_flash_setrw(int to)
67 {
68 unsigned int val;
69 unsigned long flags;
71 local_irq_save(flags);
72 val = __raw_readb(BAST_VA_CTRL3);
74 if (to)
75 val |= BAST_CPLD_CTRL3_ROMWEN;
76 else
77 val &= ~BAST_CPLD_CTRL3_ROMWEN;
79 pr_debug("new cpld ctrl3=%02x\n", val);
81 __raw_writeb(val, BAST_VA_CTRL3);
82 local_irq_restore(flags);
83 }
85 static int bast_flash_remove(struct platform_device *pdev)
86 {
87 struct bast_flash_info *info = platform_get_drvdata(pdev);
89 platform_set_drvdata(pdev, NULL);
91 if (info == NULL)
92 return 0;
94 if (info->map.virt != NULL)
95 iounmap(info->map.virt);
97 if (info->mtd) {
98 del_mtd_partitions(info->mtd);
99 map_destroy(info->mtd);
100 }
102 kfree(info->partitions);
104 if (info->area) {
105 release_resource(info->area);
106 kfree(info->area);
107 }
109 kfree(info);
111 return 0;
112 }
114 static int bast_flash_probe(struct platform_device *pdev)
115 {
116 struct bast_flash_info *info;
117 struct resource *res;
118 int err = 0;
120 info = kmalloc(sizeof(*info), GFP_KERNEL);
121 if (info == NULL) {
122 printk(KERN_ERR PFX "no memory for flash info\n");
123 err = -ENOMEM;
124 goto exit_error;
125 }
127 memzero(info, sizeof(*info));
128 platform_set_drvdata(pdev, info);
130 res = pdev->resource; /* assume that the flash has one resource */
132 info->map.phys = res->start;
133 info->map.size = res->end - res->start + 1;
134 info->map.name = pdev->dev.bus_id;
135 info->map.bankwidth = 2;
137 if (info->map.size > AREA_MAXSIZE)
138 info->map.size = AREA_MAXSIZE;
140 pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__,
141 info->map.phys, info->map.size);
143 info->area = request_mem_region(res->start, info->map.size,
144 pdev->name);
145 if (info->area == NULL) {
146 printk(KERN_ERR PFX "cannot reserve flash memory region\n");
147 err = -ENOENT;
148 goto exit_error;
149 }
151 info->map.virt = ioremap(res->start, info->map.size);
152 pr_debug("%s: virt at %08x\n", __FUNCTION__, (int)info->map.virt);
154 if (info->map.virt == 0) {
155 printk(KERN_ERR PFX "failed to ioremap() region\n");
156 err = -EIO;
157 goto exit_error;
158 }
160 simple_map_init(&info->map);
162 /* enable the write to the flash area */
164 bast_flash_setrw(1);
166 /* probe for the device(s) */
168 info->mtd = do_map_probe("jedec_probe", &info->map);
169 if (info->mtd == NULL)
170 info->mtd = do_map_probe("cfi_probe", &info->map);
172 if (info->mtd == NULL) {
173 printk(KERN_ERR PFX "map_probe() failed\n");
174 err = -ENXIO;
175 goto exit_error;
176 }
178 /* mark ourselves as the owner */
179 info->mtd->owner = THIS_MODULE;
181 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
182 if (err > 0) {
183 err = add_mtd_partitions(info->mtd, info->partitions, err);
184 if (err)
185 printk(KERN_ERR PFX "cannot add/parse partitions\n");
186 } else {
187 err = add_mtd_device(info->mtd);
188 }
190 if (err == 0)
191 return 0;
193 /* fall through to exit error */
195 exit_error:
196 bast_flash_remove(pdev);
197 return err;
198 }
200 static struct platform_driver bast_flash_driver = {
201 .probe = bast_flash_probe,
202 .remove = bast_flash_remove,
203 .driver = {
204 .name = "bast-nor",
205 .owner = THIS_MODULE,
206 },
207 };
209 static int __init bast_flash_init(void)
210 {
211 printk("BAST NOR-Flash Driver, (c) 2004 Simtec Electronics\n");
212 return platform_driver_register(&bast_flash_driver);
213 }
215 static void __exit bast_flash_exit(void)
216 {
217 platform_driver_unregister(&bast_flash_driver);
218 }
220 module_init(bast_flash_init);
221 module_exit(bast_flash_exit);
223 MODULE_LICENSE("GPL");
224 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
225 MODULE_DESCRIPTION("BAST MTD Map driver");