ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/omap_nor.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 * Flash memory support for various TI OMAP boards
3 *
4 * Copyright (C) 2001-2002 MontaVista Software Inc.
5 * Copyright (C) 2003-2004 Texas Instruments
6 * Copyright (C) 2004 Nokia Corporation
7 *
8 * Assembled using driver code copyright the companies above
9 * and written by David Brownell, Jian Zhang <jzhang@ti.com>,
10 * Tony Lindgren <tony@atomide.com> and others.
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 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
33 #include <linux/platform_device.h>
34 #include <linux/module.h>
35 #include <linux/types.h>
36 #include <linux/kernel.h>
37 #include <linux/init.h>
38 #include <linux/ioport.h>
39 #include <linux/slab.h>
41 #include <linux/mtd/mtd.h>
42 #include <linux/mtd/map.h>
43 #include <linux/mtd/partitions.h>
45 #include <asm/io.h>
46 #include <asm/hardware.h>
47 #include <asm/mach/flash.h>
48 #include <asm/arch/tc.h>
50 #ifdef CONFIG_MTD_PARTITIONS
51 static const char *part_probes[] = { /* "RedBoot", */ "cmdlinepart", NULL };
52 #endif
54 struct omapflash_info {
55 struct mtd_partition *parts;
56 struct mtd_info *mtd;
57 struct map_info map;
58 };
60 static void omap_set_vpp(struct map_info *map, int enable)
61 {
62 static int count;
64 if (enable) {
65 if (count++ == 0)
66 OMAP_EMIFS_CONFIG_REG |= OMAP_EMIFS_CONFIG_WP;
67 } else {
68 if (count && (--count == 0))
69 OMAP_EMIFS_CONFIG_REG &= ~OMAP_EMIFS_CONFIG_WP;
70 }
71 }
73 static int __devinit omapflash_probe(struct platform_device *pdev)
74 {
75 int err;
76 struct omapflash_info *info;
77 struct flash_platform_data *pdata = pdev->dev.platform_data;
78 struct resource *res = pdev->resource;
79 unsigned long size = res->end - res->start + 1;
81 info = kmalloc(sizeof(struct omapflash_info), GFP_KERNEL);
82 if (!info)
83 return -ENOMEM;
85 memset(info, 0, sizeof(struct omapflash_info));
87 if (!request_mem_region(res->start, size, "flash")) {
88 err = -EBUSY;
89 goto out_free_info;
90 }
92 info->map.virt = ioremap(res->start, size);
93 if (!info->map.virt) {
94 err = -ENOMEM;
95 goto out_release_mem_region;
96 }
97 info->map.name = pdev->dev.bus_id;
98 info->map.phys = res->start;
99 info->map.size = size;
100 info->map.bankwidth = pdata->width;
101 info->map.set_vpp = omap_set_vpp;
103 simple_map_init(&info->map);
104 info->mtd = do_map_probe(pdata->map_name, &info->map);
105 if (!info->mtd) {
106 err = -EIO;
107 goto out_iounmap;
108 }
109 info->mtd->owner = THIS_MODULE;
111 #ifdef CONFIG_MTD_PARTITIONS
112 err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
113 if (err > 0)
114 add_mtd_partitions(info->mtd, info->parts, err);
115 else if (err < 0 && pdata->parts)
116 add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
117 else
118 #endif
119 add_mtd_device(info->mtd);
121 platform_set_drvdata(pdev, info);
123 return 0;
125 out_iounmap:
126 iounmap(info->map.virt);
127 out_release_mem_region:
128 release_mem_region(res->start, size);
129 out_free_info:
130 kfree(info);
132 return err;
133 }
135 static int __devexit omapflash_remove(struct platform_device *pdev)
136 {
137 struct omapflash_info *info = platform_get_drvdata(pdev);
139 platform_set_drvdata(pdev, NULL);
141 if (info) {
142 if (info->parts) {
143 del_mtd_partitions(info->mtd);
144 kfree(info->parts);
145 } else
146 del_mtd_device(info->mtd);
147 map_destroy(info->mtd);
148 release_mem_region(info->map.phys, info->map.size);
149 iounmap((void __iomem *) info->map.virt);
150 kfree(info);
151 }
153 return 0;
154 }
156 static struct platform_driver omapflash_driver = {
157 .probe = omapflash_probe,
158 .remove = __devexit_p(omapflash_remove),
159 .driver = {
160 .name = "omapflash",
161 },
162 };
164 static int __init omapflash_init(void)
165 {
166 return platform_driver_register(&omapflash_driver);
167 }
169 static void __exit omapflash_exit(void)
170 {
171 platform_driver_unregister(&omapflash_driver);
172 }
174 module_init(omapflash_init);
175 module_exit(omapflash_exit);
177 MODULE_LICENSE("GPL");
178 MODULE_DESCRIPTION("MTD NOR map driver for TI OMAP boards");