ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/nettel.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 /*
4 * nettel.c -- mappings for NETtel/SecureEdge/SnapGear (x86) boards.
5 *
6 * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
7 * (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
8 *
9 * $Id: nettel.c,v 1.12 2005/11/29 14:30:00 gleixner Exp $
10 */
12 /****************************************************************************/
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/mtd/mtd.h>
19 #include <linux/mtd/map.h>
20 #include <linux/mtd/partitions.h>
21 #include <linux/mtd/cfi.h>
22 #include <linux/reboot.h>
23 #include <linux/kdev_t.h>
24 #include <linux/root_dev.h>
25 #include <asm/io.h>
27 /****************************************************************************/
29 #define INTEL_BUSWIDTH 1
30 #define AMD_WINDOW_MAXSIZE 0x00200000
31 #define AMD_BUSWIDTH 1
33 /*
34 * PAR masks and shifts, assuming 64K pages.
35 */
36 #define SC520_PAR_ADDR_MASK 0x00003fff
37 #define SC520_PAR_ADDR_SHIFT 16
38 #define SC520_PAR_TO_ADDR(par) \
39 (((par)&SC520_PAR_ADDR_MASK) << SC520_PAR_ADDR_SHIFT)
41 #define SC520_PAR_SIZE_MASK 0x01ffc000
42 #define SC520_PAR_SIZE_SHIFT 2
43 #define SC520_PAR_TO_SIZE(par) \
44 ((((par)&SC520_PAR_SIZE_MASK) << SC520_PAR_SIZE_SHIFT) + (64*1024))
46 #define SC520_PAR(cs, addr, size) \
47 ((cs) | \
48 ((((size)-(64*1024)) >> SC520_PAR_SIZE_SHIFT) & SC520_PAR_SIZE_MASK) | \
49 (((addr) >> SC520_PAR_ADDR_SHIFT) & SC520_PAR_ADDR_MASK))
51 #define SC520_PAR_BOOTCS 0x8a000000
52 #define SC520_PAR_ROMCS1 0xaa000000
53 #define SC520_PAR_ROMCS2 0xca000000 /* Cache disabled, 64K page */
55 static void *nettel_mmcrp = NULL;
57 #ifdef CONFIG_MTD_CFI_INTELEXT
58 static struct mtd_info *intel_mtd;
59 #endif
60 static struct mtd_info *amd_mtd;
62 /****************************************************************************/
64 /****************************************************************************/
66 #ifdef CONFIG_MTD_CFI_INTELEXT
67 static struct map_info nettel_intel_map = {
68 .name = "SnapGear Intel",
69 .size = 0,
70 .bankwidth = INTEL_BUSWIDTH,
71 };
73 static struct mtd_partition nettel_intel_partitions[] = {
74 {
75 .name = "SnapGear kernel",
76 .offset = 0,
77 .size = 0x000e0000
78 },
79 {
80 .name = "SnapGear filesystem",
81 .offset = 0x00100000,
82 },
83 {
84 .name = "SnapGear config",
85 .offset = 0x000e0000,
86 .size = 0x00020000
87 },
88 {
89 .name = "SnapGear Intel",
90 .offset = 0
91 },
92 {
93 .name = "SnapGear BIOS Config",
94 .offset = 0x007e0000,
95 .size = 0x00020000
96 },
97 {
98 .name = "SnapGear BIOS",
99 .offset = 0x007e0000,
100 .size = 0x00020000
101 },
102 };
103 #endif
105 static struct map_info nettel_amd_map = {
106 .name = "SnapGear AMD",
107 .size = AMD_WINDOW_MAXSIZE,
108 .bankwidth = AMD_BUSWIDTH,
109 };
111 static struct mtd_partition nettel_amd_partitions[] = {
112 {
113 .name = "SnapGear BIOS config",
114 .offset = 0x000e0000,
115 .size = 0x00010000
116 },
117 {
118 .name = "SnapGear BIOS",
119 .offset = 0x000f0000,
120 .size = 0x00010000
121 },
122 {
123 .name = "SnapGear AMD",
124 .offset = 0
125 },
126 {
127 .name = "SnapGear high BIOS",
128 .offset = 0x001f0000,
129 .size = 0x00010000
130 }
131 };
133 #define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions)
135 /****************************************************************************/
137 #ifdef CONFIG_MTD_CFI_INTELEXT
139 /*
140 * Set the Intel flash back to read mode since some old boot
141 * loaders don't.
142 */
143 static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val, void *v)
144 {
145 struct cfi_private *cfi = nettel_intel_map.fldrv_priv;
146 unsigned long b;
148 /* Make sure all FLASH chips are put back into read mode */
149 for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {
150 cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,
151 cfi->device_type, NULL);
152 }
153 return(NOTIFY_OK);
154 }
156 static struct notifier_block nettel_notifier_block = {
157 nettel_reboot_notifier, NULL, 0
158 };
160 /*
161 * Erase the configuration file system.
162 * Used to support the software reset button.
163 */
164 static void nettel_erasecallback(struct erase_info *done)
165 {
166 wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
167 wake_up(wait_q);
168 }
170 static struct erase_info nettel_erase;
172 int nettel_eraseconfig(void)
173 {
174 struct mtd_info *mtd;
175 DECLARE_WAITQUEUE(wait, current);
176 wait_queue_head_t wait_q;
177 int ret;
179 init_waitqueue_head(&wait_q);
180 mtd = get_mtd_device(NULL, 2);
181 if (mtd) {
182 nettel_erase.mtd = mtd;
183 nettel_erase.callback = nettel_erasecallback;
184 nettel_erase.callback = NULL;
185 nettel_erase.addr = 0;
186 nettel_erase.len = mtd->size;
187 nettel_erase.priv = (u_long) &wait_q;
188 nettel_erase.priv = 0;
190 set_current_state(TASK_INTERRUPTIBLE);
191 add_wait_queue(&wait_q, &wait);
193 ret = mtd->erase(mtd, &nettel_erase);
194 if (ret) {
195 set_current_state(TASK_RUNNING);
196 remove_wait_queue(&wait_q, &wait);
197 put_mtd_device(mtd);
198 return(ret);
199 }
201 schedule(); /* Wait for erase to finish. */
202 remove_wait_queue(&wait_q, &wait);
204 put_mtd_device(mtd);
205 }
207 return(0);
208 }
210 #else
212 int nettel_eraseconfig(void)
213 {
214 return(0);
215 }
217 #endif
219 /****************************************************************************/
221 int __init nettel_init(void)
222 {
223 volatile unsigned long *amdpar;
224 unsigned long amdaddr, maxsize;
225 int num_amd_partitions=0;
226 #ifdef CONFIG_MTD_CFI_INTELEXT
227 volatile unsigned long *intel0par, *intel1par;
228 unsigned long orig_bootcspar, orig_romcs1par;
229 unsigned long intel0addr, intel0size;
230 unsigned long intel1addr, intel1size;
231 int intelboot, intel0cs, intel1cs;
232 int num_intel_partitions;
233 #endif
234 int rc = 0;
236 nettel_mmcrp = (void *) ioremap_nocache(0xfffef000, 4096);
237 if (nettel_mmcrp == NULL) {
238 printk("SNAPGEAR: failed to disable MMCR cache??\n");
239 return(-EIO);
240 }
242 /* Set CPU clock to be 33.000MHz */
243 *((unsigned char *) (nettel_mmcrp + 0xc64)) = 0x01;
245 amdpar = (volatile unsigned long *) (nettel_mmcrp + 0xc4);
247 #ifdef CONFIG_MTD_CFI_INTELEXT
248 intelboot = 0;
249 intel0cs = SC520_PAR_ROMCS1;
250 intel0par = (volatile unsigned long *) (nettel_mmcrp + 0xc0);
251 intel1cs = SC520_PAR_ROMCS2;
252 intel1par = (volatile unsigned long *) (nettel_mmcrp + 0xbc);
254 /*
255 * Save the CS settings then ensure ROMCS1 and ROMCS2 are off,
256 * otherwise they might clash with where we try to map BOOTCS.
257 */
258 orig_bootcspar = *amdpar;
259 orig_romcs1par = *intel0par;
260 *intel0par = 0;
261 *intel1par = 0;
262 #endif
264 /*
265 * The first thing to do is determine if we have a separate
266 * boot FLASH device. Typically this is a small (1 to 2MB)
267 * AMD FLASH part. It seems that device size is about the
268 * only way to tell if this is the case...
269 */
270 amdaddr = 0x20000000;
271 maxsize = AMD_WINDOW_MAXSIZE;
273 *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize);
274 __asm__ ("wbinvd");
276 nettel_amd_map.phys = amdaddr;
277 nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize);
278 if (!nettel_amd_map.virt) {
279 printk("SNAPGEAR: failed to ioremap() BOOTCS\n");
280 return(-EIO);
281 }
282 simple_map_init(&nettel_amd_map);
284 if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) {
285 printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n",
286 amd_mtd->size>>10);
288 amd_mtd->owner = THIS_MODULE;
290 /* The high BIOS partition is only present for 2MB units */
291 num_amd_partitions = NUM_AMD_PARTITIONS;
292 if (amd_mtd->size < AMD_WINDOW_MAXSIZE)
293 num_amd_partitions--;
294 /* Don't add the partition until after the primary INTEL's */
296 #ifdef CONFIG_MTD_CFI_INTELEXT
297 /*
298 * Map the Intel flash into memory after the AMD
299 * It has to start on a multiple of maxsize.
300 */
301 maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);
302 if (maxsize < (32 * 1024 * 1024))
303 maxsize = (32 * 1024 * 1024);
304 intel0addr = amdaddr + maxsize;
305 #endif
306 } else {
307 #ifdef CONFIG_MTD_CFI_INTELEXT
308 /* INTEL boot FLASH */
309 intelboot++;
311 if (!orig_romcs1par) {
312 intel0cs = SC520_PAR_BOOTCS;
313 intel0par = (volatile unsigned long *)
314 (nettel_mmcrp + 0xc4);
315 intel1cs = SC520_PAR_ROMCS1;
316 intel1par = (volatile unsigned long *)
317 (nettel_mmcrp + 0xc0);
319 intel0addr = SC520_PAR_TO_ADDR(orig_bootcspar);
320 maxsize = SC520_PAR_TO_SIZE(orig_bootcspar);
321 } else {
322 /* Kernel base is on ROMCS1, not BOOTCS */
323 intel0cs = SC520_PAR_ROMCS1;
324 intel0par = (volatile unsigned long *)
325 (nettel_mmcrp + 0xc0);
326 intel1cs = SC520_PAR_BOOTCS;
327 intel1par = (volatile unsigned long *)
328 (nettel_mmcrp + 0xc4);
330 intel0addr = SC520_PAR_TO_ADDR(orig_romcs1par);
331 maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);
332 }
334 /* Destroy useless AMD MTD mapping */
335 amd_mtd = NULL;
336 iounmap(nettel_amd_map.virt);
337 nettel_amd_map.virt = NULL;
338 #else
339 /* Only AMD flash supported */
340 return(-ENXIO);
341 #endif
342 }
344 #ifdef CONFIG_MTD_CFI_INTELEXT
345 /*
346 * We have determined the INTEL FLASH configuration, so lets
347 * go ahead and probe for them now.
348 */
350 /* Set PAR to the maximum size */
351 if (maxsize < (32 * 1024 * 1024))
352 maxsize = (32 * 1024 * 1024);
353 *intel0par = SC520_PAR(intel0cs, intel0addr, maxsize);
355 /* Turn other PAR off so the first probe doesn't find it */
356 *intel1par = 0;
358 /* Probe for the the size of the first Intel flash */
359 nettel_intel_map.size = maxsize;
360 nettel_intel_map.phys = intel0addr;
361 nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
362 if (!nettel_intel_map.virt) {
363 printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
364 return(-EIO);
365 }
366 simple_map_init(&nettel_intel_map);
368 intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
369 if (!intel_mtd) {
370 iounmap(nettel_intel_map.virt);
371 return(-ENXIO);
372 }
374 /* Set PAR to the detected size */
375 intel0size = intel_mtd->size;
376 *intel0par = SC520_PAR(intel0cs, intel0addr, intel0size);
378 /*
379 * Map second Intel FLASH right after first. Set its size to the
380 * same maxsize used for the first Intel FLASH.
381 */
382 intel1addr = intel0addr + intel0size;
383 *intel1par = SC520_PAR(intel1cs, intel1addr, maxsize);
384 __asm__ ("wbinvd");
386 maxsize += intel0size;
388 /* Delete the old map and probe again to do both chips */
389 map_destroy(intel_mtd);
390 intel_mtd = NULL;
391 iounmap(nettel_intel_map.virt);
393 nettel_intel_map.size = maxsize;
394 nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
395 if (!nettel_intel_map.virt) {
396 printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
397 return(-EIO);
398 }
400 intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
401 if (! intel_mtd) {
402 iounmap((void *) nettel_intel_map.virt);
403 return(-ENXIO);
404 }
406 intel1size = intel_mtd->size - intel0size;
407 if (intel1size > 0) {
408 *intel1par = SC520_PAR(intel1cs, intel1addr, intel1size);
409 __asm__ ("wbinvd");
410 } else {
411 *intel1par = 0;
412 }
414 printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %dK\n",
415 (intel_mtd->size >> 10));
417 intel_mtd->owner = THIS_MODULE;
419 #ifndef CONFIG_BLK_DEV_INITRD
420 ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1);
421 #endif
423 num_intel_partitions = sizeof(nettel_intel_partitions) /
424 sizeof(nettel_intel_partitions[0]);
426 if (intelboot) {
427 /*
428 * Adjust offset and size of last boot partition.
429 * Must allow for BIOS region at end of FLASH.
430 */
431 nettel_intel_partitions[1].size = (intel0size + intel1size) -
432 (1024*1024 + intel_mtd->erasesize);
433 nettel_intel_partitions[3].size = intel0size + intel1size;
434 nettel_intel_partitions[4].offset =
435 (intel0size + intel1size) - intel_mtd->erasesize;
436 nettel_intel_partitions[4].size = intel_mtd->erasesize;
437 nettel_intel_partitions[5].offset =
438 nettel_intel_partitions[4].offset;
439 nettel_intel_partitions[5].size =
440 nettel_intel_partitions[4].size;
441 } else {
442 /* No BIOS regions when AMD boot */
443 num_intel_partitions -= 2;
444 }
445 rc = add_mtd_partitions(intel_mtd, nettel_intel_partitions,
446 num_intel_partitions);
447 #endif
449 if (amd_mtd) {
450 rc = add_mtd_partitions(amd_mtd, nettel_amd_partitions,
451 num_amd_partitions);
452 }
454 #ifdef CONFIG_MTD_CFI_INTELEXT
455 register_reboot_notifier(&nettel_notifier_block);
456 #endif
458 return(rc);
459 }
461 /****************************************************************************/
463 void __exit nettel_cleanup(void)
464 {
465 #ifdef CONFIG_MTD_CFI_INTELEXT
466 unregister_reboot_notifier(&nettel_notifier_block);
467 #endif
468 if (amd_mtd) {
469 del_mtd_partitions(amd_mtd);
470 map_destroy(amd_mtd);
471 }
472 if (nettel_amd_map.virt) {
473 iounmap(nettel_amd_map.virt);
474 nettel_amd_map.virt = NULL;
475 }
476 #ifdef CONFIG_MTD_CFI_INTELEXT
477 if (intel_mtd) {
478 del_mtd_partitions(intel_mtd);
479 map_destroy(intel_mtd);
480 }
481 if (nettel_intel_map.virt) {
482 iounmap(nettel_intel_map.virt);
483 nettel_intel_map.virt = NULL;
484 }
485 #endif
486 }
488 /****************************************************************************/
490 module_init(nettel_init);
491 module_exit(nettel_cleanup);
493 MODULE_LICENSE("GPL");
494 MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
495 MODULE_DESCRIPTION("SnapGear/SecureEdge FLASH support");
497 /****************************************************************************/