ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/ixp4xx.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 * $Id: ixp4xx.c,v 1.13 2005/11/16 16:23:21 dvrabel Exp $
3 *
4 * drivers/mtd/maps/ixp4xx.c
5 *
6 * MTD Map file for IXP4XX based systems. Please do not make per-board
7 * changes in here. If your board needs special setup, do it in your
8 * platform level code in arch/arm/mach-ixp4xx/board-setup.c
9 *
10 * Original Author: Intel Corporation
11 * Maintainer: Deepak Saxena <dsaxena@mvista.com>
12 *
13 * Copyright (C) 2002 Intel Corporation
14 * Copyright (C) 2003-2004 MontaVista Software, Inc.
15 *
16 */
18 #include <linux/module.h>
19 #include <linux/types.h>
20 #include <linux/init.h>
21 #include <linux/kernel.h>
22 #include <linux/string.h>
23 #include <linux/slab.h>
24 #include <linux/ioport.h>
25 #include <linux/device.h>
26 #include <linux/platform_device.h>
28 #include <linux/mtd/mtd.h>
29 #include <linux/mtd/map.h>
30 #include <linux/mtd/partitions.h>
32 #include <asm/io.h>
33 #include <asm/mach/flash.h>
35 #include <linux/reboot.h>
37 /*
38 * Read/write a 16 bit word from flash address 'addr'.
39 *
40 * When the cpu is in little-endian mode it swizzles the address lines
41 * ('address coherency') so we need to undo the swizzling to ensure commands
42 * and the like end up on the correct flash address.
43 *
44 * To further complicate matters, due to the way the expansion bus controller
45 * handles 32 bit reads, the byte stream ABCD is stored on the flash as:
46 * D15 D0
47 * +---+---+
48 * | A | B | 0
49 * +---+---+
50 * | C | D | 2
51 * +---+---+
52 * This means that on LE systems each 16 bit word must be swapped. Note that
53 * this requires CONFIG_MTD_CFI_BE_BYTE_SWAP to be enabled to 'unswap' the CFI
54 * data and other flash commands which are always in D7-D0.
55 */
56 #ifndef __ARMEB__
57 #ifndef CONFIG_MTD_CFI_BE_BYTE_SWAP
58 # error CONFIG_MTD_CFI_BE_BYTE_SWAP required
59 #endif
61 static inline u16 flash_read16(void __iomem *addr)
62 {
63 return be16_to_cpu(__raw_readw((void __iomem *)((unsigned long)addr ^ 0x2)));
64 }
66 static inline void flash_write16(u16 d, void __iomem *addr)
67 {
68 __raw_writew(cpu_to_be16(d), (void __iomem *)((unsigned long)addr ^ 0x2));
69 }
71 #define BYTE0(h) ((h) & 0xFF)
72 #define BYTE1(h) (((h) >> 8) & 0xFF)
74 #else
76 static inline u16 flash_read16(const void __iomem *addr)
77 {
78 return __raw_readw(addr);
79 }
81 static inline void flash_write16(u16 d, void __iomem *addr)
82 {
83 __raw_writew(d, addr);
84 }
86 #define BYTE0(h) (((h) >> 8) & 0xFF)
87 #define BYTE1(h) ((h) & 0xFF)
88 #endif
90 static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
91 {
92 map_word val;
93 val.x[0] = flash_read16(map->virt + ofs);
94 return val;
95 }
97 /*
98 * The IXP4xx expansion bus only allows 16-bit wide acceses
99 * when attached to a 16-bit wide device (such as the 28F128J3A),
100 * so we can't just memcpy_fromio().
101 */
102 static void ixp4xx_copy_from(struct map_info *map, void *to,
103 unsigned long from, ssize_t len)
104 {
105 u8 *dest = (u8 *) to;
106 void __iomem *src = map->virt + from;
108 if (len <= 0)
109 return;
111 if (from & 1) {
112 *dest++ = BYTE1(flash_read16(src));
113 src++;
114 --len;
115 }
117 while (len >= 2) {
118 u16 data = flash_read16(src);
119 *dest++ = BYTE0(data);
120 *dest++ = BYTE1(data);
121 src += 2;
122 len -= 2;
123 }
125 if (len > 0)
126 *dest++ = BYTE0(flash_read16(src));
127 }
129 /*
130 * Unaligned writes are ignored, causing the 8-bit
131 * probe to fail and proceed to the 16-bit probe (which succeeds).
132 */
133 static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
134 {
135 if (!(adr & 1))
136 flash_write16(d.x[0], map->virt + adr);
137 }
139 /*
140 * Fast write16 function without the probing check above
141 */
142 static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
143 {
144 flash_write16(d.x[0], map->virt + adr);
145 }
147 struct ixp4xx_flash_info {
148 struct mtd_info *mtd;
149 struct map_info map;
150 struct mtd_partition *partitions;
151 struct resource *res;
152 };
154 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
156 static int ixp4xx_flash_remove(struct platform_device *dev)
157 {
158 struct flash_platform_data *plat = dev->dev.platform_data;
159 struct ixp4xx_flash_info *info = platform_get_drvdata(dev);
161 platform_set_drvdata(dev, NULL);
163 if(!info)
164 return 0;
166 if (info->mtd) {
167 del_mtd_partitions(info->mtd);
168 map_destroy(info->mtd);
169 }
170 if (info->map.virt)
171 iounmap(info->map.virt);
173 kfree(info->partitions);
175 if (info->res) {
176 release_resource(info->res);
177 kfree(info->res);
178 }
180 if (plat->exit)
181 plat->exit();
183 return 0;
184 }
186 static int ixp4xx_flash_probe(struct platform_device *dev)
187 {
188 struct flash_platform_data *plat = dev->dev.platform_data;
189 struct ixp4xx_flash_info *info;
190 int err = -1;
192 if (!plat)
193 return -ENODEV;
195 if (plat->init) {
196 err = plat->init();
197 if (err)
198 return err;
199 }
201 info = kmalloc(sizeof(struct ixp4xx_flash_info), GFP_KERNEL);
202 if(!info) {
203 err = -ENOMEM;
204 goto Error;
205 }
206 memzero(info, sizeof(struct ixp4xx_flash_info));
208 platform_set_drvdata(dev, info);
210 /*
211 * Tell the MTD layer we're not 1:1 mapped so that it does
212 * not attempt to do a direct access on us.
213 */
214 info->map.phys = NO_XIP;
215 info->map.size = dev->resource->end - dev->resource->start + 1;
217 /*
218 * We only support 16-bit accesses for now. If and when
219 * any board use 8-bit access, we'll fixup the driver to
220 * handle that.
221 */
222 info->map.bankwidth = 2;
223 info->map.name = dev->dev.bus_id;
224 info->map.read = ixp4xx_read16,
225 info->map.write = ixp4xx_probe_write16,
226 info->map.copy_from = ixp4xx_copy_from,
228 info->res = request_mem_region(dev->resource->start,
229 dev->resource->end - dev->resource->start + 1,
230 "IXP4XXFlash");
231 if (!info->res) {
232 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
233 err = -ENOMEM;
234 goto Error;
235 }
237 info->map.virt = ioremap(dev->resource->start,
238 dev->resource->end - dev->resource->start + 1);
239 if (!info->map.virt) {
240 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
241 err = -EIO;
242 goto Error;
243 }
245 info->mtd = do_map_probe(plat->map_name, &info->map);
246 if (!info->mtd) {
247 printk(KERN_ERR "IXP4XXFlash: map_probe failed\n");
248 err = -ENXIO;
249 goto Error;
250 }
251 info->mtd->owner = THIS_MODULE;
253 /* Use the fast version */
254 info->map.write = ixp4xx_write16,
256 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
257 if (err > 0) {
258 err = add_mtd_partitions(info->mtd, info->partitions, err);
259 if(err)
260 printk(KERN_ERR "Could not parse partitions\n");
261 }
263 if (err)
264 goto Error;
266 return 0;
268 Error:
269 ixp4xx_flash_remove(dev);
270 return err;
271 }
273 static struct platform_driver ixp4xx_flash_driver = {
274 .probe = ixp4xx_flash_probe,
275 .remove = ixp4xx_flash_remove,
276 .driver = {
277 .name = "IXP4XX-Flash",
278 },
279 };
281 static int __init ixp4xx_flash_init(void)
282 {
283 return platform_driver_register(&ixp4xx_flash_driver);
284 }
286 static void __exit ixp4xx_flash_exit(void)
287 {
288 platform_driver_unregister(&ixp4xx_flash_driver);
289 }
292 module_init(ixp4xx_flash_init);
293 module_exit(ixp4xx_flash_exit);
295 MODULE_LICENSE("GPL");
296 MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
297 MODULE_AUTHOR("Deepak Saxena");