ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/integrator-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 /*======================================================================
3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
5 Copyright (C) 2000 ARM Limited
6 Copyright (C) 2003 Deep Blue Solutions Ltd.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 This is access code for flashes using ARM's flash partitioning
23 standards.
25 $Id: integrator-flash.c,v 1.20 2005/11/07 11:14:27 gleixner Exp $
27 ======================================================================*/
29 #include <linux/module.h>
30 #include <linux/types.h>
31 #include <linux/kernel.h>
32 #include <linux/slab.h>
33 #include <linux/ioport.h>
34 #include <linux/platform_device.h>
35 #include <linux/init.h>
37 #include <linux/mtd/mtd.h>
38 #include <linux/mtd/map.h>
39 #include <linux/mtd/partitions.h>
41 #include <asm/mach/flash.h>
42 #include <asm/hardware.h>
43 #include <asm/io.h>
44 #include <asm/system.h>
46 #ifdef CONFIG_ARCH_P720T
47 #define FLASH_BASE (0x04000000)
48 #define FLASH_SIZE (64*1024*1024)
49 #endif
51 struct armflash_info {
52 struct flash_platform_data *plat;
53 struct resource *res;
54 struct mtd_partition *parts;
55 struct mtd_info *mtd;
56 struct map_info map;
57 };
59 static void armflash_set_vpp(struct map_info *map, int on)
60 {
61 struct armflash_info *info = container_of(map, struct armflash_info, map);
63 if (info->plat && info->plat->set_vpp)
64 info->plat->set_vpp(on);
65 }
67 static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL };
69 static int armflash_probe(struct platform_device *dev)
70 {
71 struct flash_platform_data *plat = dev->dev.platform_data;
72 struct resource *res = dev->resource;
73 unsigned int size = res->end - res->start + 1;
74 struct armflash_info *info;
75 int err;
76 void __iomem *base;
78 info = kmalloc(sizeof(struct armflash_info), GFP_KERNEL);
79 if (!info) {
80 err = -ENOMEM;
81 goto out;
82 }
84 memset(info, 0, sizeof(struct armflash_info));
86 info->plat = plat;
87 if (plat && plat->init) {
88 err = plat->init();
89 if (err)
90 goto no_resource;
91 }
93 info->res = request_mem_region(res->start, size, "armflash");
94 if (!info->res) {
95 err = -EBUSY;
96 goto no_resource;
97 }
99 base = ioremap(res->start, size);
100 if (!base) {
101 err = -ENOMEM;
102 goto no_mem;
103 }
105 /*
106 * look for CFI based flash parts fitted to this board
107 */
108 info->map.size = size;
109 info->map.bankwidth = plat->width;
110 info->map.phys = res->start;
111 info->map.virt = base;
112 info->map.name = dev->dev.bus_id;
113 info->map.set_vpp = armflash_set_vpp;
115 simple_map_init(&info->map);
117 /*
118 * Also, the CFI layer automatically works out what size
119 * of chips we have, and does the necessary identification
120 * for us automatically.
121 */
122 info->mtd = do_map_probe(plat->map_name, &info->map);
123 if (!info->mtd) {
124 err = -ENXIO;
125 goto no_device;
126 }
128 info->mtd->owner = THIS_MODULE;
130 err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0);
131 if (err > 0) {
132 err = add_mtd_partitions(info->mtd, info->parts, err);
133 if (err)
134 printk(KERN_ERR
135 "mtd partition registration failed: %d\n", err);
136 }
138 if (err == 0)
139 platform_set_drvdata(dev, info);
141 /*
142 * If we got an error, free all resources.
143 */
144 if (err < 0) {
145 if (info->mtd) {
146 del_mtd_partitions(info->mtd);
147 map_destroy(info->mtd);
148 }
149 kfree(info->parts);
151 no_device:
152 iounmap(base);
153 no_mem:
154 release_mem_region(res->start, size);
155 no_resource:
156 if (plat && plat->exit)
157 plat->exit();
158 kfree(info);
159 }
160 out:
161 return err;
162 }
164 static int armflash_remove(struct platform_device *dev)
165 {
166 struct armflash_info *info = platform_get_drvdata(dev);
168 platform_set_drvdata(dev, NULL);
170 if (info) {
171 if (info->mtd) {
172 del_mtd_partitions(info->mtd);
173 map_destroy(info->mtd);
174 }
175 kfree(info->parts);
177 iounmap(info->map.virt);
178 release_resource(info->res);
179 kfree(info->res);
181 if (info->plat && info->plat->exit)
182 info->plat->exit();
184 kfree(info);
185 }
187 return 0;
188 }
190 static struct platform_driver armflash_driver = {
191 .probe = armflash_probe,
192 .remove = armflash_remove,
193 .driver = {
194 .name = "armflash",
195 },
196 };
198 static int __init armflash_init(void)
199 {
200 return platform_driver_register(&armflash_driver);
201 }
203 static void __exit armflash_exit(void)
204 {
205 platform_driver_unregister(&armflash_driver);
206 }
208 module_init(armflash_init);
209 module_exit(armflash_exit);
211 MODULE_AUTHOR("ARM Ltd");
212 MODULE_DESCRIPTION("ARM Integrator CFI map driver");
213 MODULE_LICENSE("GPL");