ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/ceiva.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 * Ceiva flash memory driver.
3 * Copyright (C) 2002 Rob Scott <rscott@mtrob.fdns.net>
4 *
5 * Note: this driver supports jedec compatible devices. Modification
6 * for CFI compatible devices should be straight forward: change
7 * jedec_probe to cfi_probe.
8 *
9 * Based on: sa1100-flash.c, which has the following copyright:
10 * Flash memory access on SA11x0 based devices
11 *
12 * (C) 2000 Nicolas Pitre <nico@cam.org>
13 *
14 * $Id: ceiva.c,v 1.11 2004/09/16 23:27:12 gleixner Exp $
15 */
17 #include <linux/module.h>
18 #include <linux/types.h>
19 #include <linux/ioport.h>
20 #include <linux/kernel.h>
21 #include <linux/init.h>
22 #include <linux/slab.h>
24 #include <linux/mtd/mtd.h>
25 #include <linux/mtd/map.h>
26 #include <linux/mtd/partitions.h>
27 #include <linux/mtd/concat.h>
29 #include <asm/hardware.h>
30 #include <asm/mach-types.h>
31 #include <asm/io.h>
32 #include <asm/sizes.h>
34 /*
35 * This isn't complete yet, so...
36 */
37 #define CONFIG_MTD_CEIVA_STATICMAP
39 #ifdef CONFIG_MTD_CEIVA_STATICMAP
40 /*
41 * See include/linux/mtd/partitions.h for definition of the mtd_partition
42 * structure.
43 *
44 * Please note:
45 * 1. The flash size given should be the largest flash size that can
46 * be accomodated.
47 *
48 * 2. The bus width must defined in clps_setup_flash.
49 *
50 * The MTD layer will detect flash chip aliasing and reduce the size of
51 * the map accordingly.
52 *
53 */
55 #ifdef CONFIG_ARCH_CEIVA
56 /* Flash / Partition sizing */
57 /* For the 28F8003, we use the block mapping to calcuate the sizes */
58 #define MAX_SIZE_KiB (16 + 8 + 8 + 96 + (7*128))
59 #define BOOT_PARTITION_SIZE_KiB (16)
60 #define PARAMS_PARTITION_SIZE_KiB (8)
61 #define KERNEL_PARTITION_SIZE_KiB (4*128)
62 /* Use both remaing portion of first flash, and all of second flash */
63 #define ROOT_PARTITION_SIZE_KiB (3*128) + (8*128)
65 static struct mtd_partition ceiva_partitions[] = {
66 {
67 .name = "Ceiva BOOT partition",
68 .size = BOOT_PARTITION_SIZE_KiB*1024,
69 .offset = 0,
71 },{
72 .name = "Ceiva parameters partition",
73 .size = PARAMS_PARTITION_SIZE_KiB*1024,
74 .offset = (16 + 8) * 1024,
75 },{
76 .name = "Ceiva kernel partition",
77 .size = (KERNEL_PARTITION_SIZE_KiB)*1024,
78 .offset = 0x20000,
80 },{
81 .name = "Ceiva root filesystem partition",
82 .offset = MTDPART_OFS_APPEND,
83 .size = (ROOT_PARTITION_SIZE_KiB)*1024,
84 }
85 };
86 #endif
88 static int __init clps_static_partitions(struct mtd_partition **parts)
89 {
90 int nb_parts = 0;
92 #ifdef CONFIG_ARCH_CEIVA
93 if (machine_is_ceiva()) {
94 *parts = ceiva_partitions;
95 nb_parts = ARRAY_SIZE(ceiva_partitions);
96 }
97 #endif
98 return nb_parts;
99 }
100 #endif
102 struct clps_info {
103 unsigned long base;
104 unsigned long size;
105 int width;
106 void *vbase;
107 struct map_info *map;
108 struct mtd_info *mtd;
109 struct resource *res;
110 };
112 #define NR_SUBMTD 4
114 static struct clps_info info[NR_SUBMTD];
116 static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info **rmtd)
117 {
118 struct mtd_info *subdev[nr];
119 struct map_info *maps;
120 int i, found = 0, ret = 0;
122 /*
123 * Allocate the map_info structs in one go.
124 */
125 maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
126 if (!maps)
127 return -ENOMEM;
128 memset(maps, 0, sizeof(struct map_info) * nr);
129 /*
130 * Claim and then map the memory regions.
131 */
132 for (i = 0; i < nr; i++) {
133 if (clps[i].base == (unsigned long)-1)
134 break;
136 clps[i].res = request_mem_region(clps[i].base, clps[i].size, "clps flash");
137 if (!clps[i].res) {
138 ret = -EBUSY;
139 break;
140 }
142 clps[i].map = maps + i;
144 clps[i].map->name = "clps flash";
145 clps[i].map->phys = clps[i].base;
147 clps[i].vbase = ioremap(clps[i].base, clps[i].size);
148 if (!clps[i].vbase) {
149 ret = -ENOMEM;
150 break;
151 }
153 clps[i].map->virt = (void __iomem *)clps[i].vbase;
154 clps[i].map->bankwidth = clps[i].width;
155 clps[i].map->size = clps[i].size;
157 simple_map_init(&clps[i].map);
159 clps[i].mtd = do_map_probe("jedec_probe", clps[i].map);
160 if (clps[i].mtd == NULL) {
161 ret = -ENXIO;
162 break;
163 }
164 clps[i].mtd->owner = THIS_MODULE;
165 subdev[i] = clps[i].mtd;
167 printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, "
168 "%d-bit\n", clps[i].base, clps[i].mtd->size >> 20,
169 clps[i].width * 8);
170 found += 1;
171 }
173 /*
174 * ENXIO is special. It means we didn't find a chip when
175 * we probed. We need to tear down the mapping, free the
176 * resource and mark it as such.
177 */
178 if (ret == -ENXIO) {
179 iounmap(clps[i].vbase);
180 clps[i].vbase = NULL;
181 release_resource(clps[i].res);
182 clps[i].res = NULL;
183 }
185 /*
186 * If we found one device, don't bother with concat support.
187 * If we found multiple devices, use concat if we have it
188 * available, otherwise fail.
189 */
190 if (ret == 0 || ret == -ENXIO) {
191 if (found == 1) {
192 *rmtd = subdev[0];
193 ret = 0;
194 } else if (found > 1) {
195 /*
196 * We detected multiple devices. Concatenate
197 * them together.
198 */
199 #ifdef CONFIG_MTD_CONCAT
200 *rmtd = mtd_concat_create(subdev, found,
201 "clps flash");
202 if (*rmtd == NULL)
203 ret = -ENXIO;
204 #else
205 printk(KERN_ERR "clps flash: multiple devices "
206 "found but MTD concat support disabled.\n");
207 ret = -ENXIO;
208 #endif
209 }
210 }
212 /*
213 * If we failed, clean up.
214 */
215 if (ret) {
216 do {
217 if (clps[i].mtd)
218 map_destroy(clps[i].mtd);
219 if (clps[i].vbase)
220 iounmap(clps[i].vbase);
221 if (clps[i].res)
222 release_resource(clps[i].res);
223 } while (i--);
225 kfree(maps);
226 }
228 return ret;
229 }
231 static void __exit clps_destroy_mtd(struct clps_info *clps, struct mtd_info *mtd)
232 {
233 int i;
235 del_mtd_partitions(mtd);
237 if (mtd != clps[0].mtd)
238 mtd_concat_destroy(mtd);
240 for (i = NR_SUBMTD; i >= 0; i--) {
241 if (clps[i].mtd)
242 map_destroy(clps[i].mtd);
243 if (clps[i].vbase)
244 iounmap(clps[i].vbase);
245 if (clps[i].res)
246 release_resource(clps[i].res);
247 }
248 kfree(clps[0].map);
249 }
251 /*
252 * We define the memory space, size, and width for the flash memory
253 * space here.
254 */
256 static int __init clps_setup_flash(void)
257 {
258 int nr;
260 #ifdef CONFIG_ARCH_CEIVA
261 if (machine_is_ceiva()) {
262 info[0].base = CS0_PHYS_BASE;
263 info[0].size = SZ_32M;
264 info[0].width = CEIVA_FLASH_WIDTH;
265 info[1].base = CS1_PHYS_BASE;
266 info[1].size = SZ_32M;
267 info[1].width = CEIVA_FLASH_WIDTH;
268 nr = 2;
269 }
270 #endif
271 return nr;
272 }
274 static struct mtd_partition *parsed_parts;
275 static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
277 static void __init clps_locate_partitions(struct mtd_info *mtd)
278 {
279 const char *part_type = NULL;
280 int nr_parts = 0;
281 do {
282 /*
283 * Partition selection stuff.
284 */
285 nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0);
286 if (nr_parts > 0) {
287 part_type = "command line";
288 break;
289 }
290 #ifdef CONFIG_MTD_CEIVA_STATICMAP
291 nr_parts = clps_static_partitions(&parsed_parts);
292 if (nr_parts > 0) {
293 part_type = "static";
294 break;
295 }
296 printk("found: %d partitions\n", nr_parts);
297 #endif
298 } while (0);
300 if (nr_parts == 0) {
301 printk(KERN_NOTICE "clps flash: no partition info "
302 "available, registering whole flash\n");
303 add_mtd_device(mtd);
304 } else {
305 printk(KERN_NOTICE "clps flash: using %s partition "
306 "definition\n", part_type);
307 add_mtd_partitions(mtd, parsed_parts, nr_parts);
308 }
310 /* Always succeeds. */
311 }
313 static void __exit clps_destroy_partitions(void)
314 {
315 kfree(parsed_parts);
316 }
318 static struct mtd_info *mymtd;
320 static int __init clps_mtd_init(void)
321 {
322 int ret;
323 int nr;
325 nr = clps_setup_flash();
326 if (nr < 0)
327 return nr;
329 ret = clps_setup_mtd(info, nr, &mymtd);
330 if (ret)
331 return ret;
333 clps_locate_partitions(mymtd);
335 return 0;
336 }
338 static void __exit clps_mtd_cleanup(void)
339 {
340 clps_destroy_mtd(info, mymtd);
341 clps_destroy_partitions();
342 }
344 module_init(clps_mtd_init);
345 module_exit(clps_mtd_cleanup);
347 MODULE_AUTHOR("Rob Scott");
348 MODULE_DESCRIPTION("Cirrus Logic JEDEC map driver");
349 MODULE_LICENSE("GPL");