ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/sun_uflash.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 /* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $
2 *
3 * sun_uflash - Driver implementation for user-programmable flash
4 * present on many Sun Microsystems SME boardsets.
5 *
6 * This driver does NOT provide access to the OBP-flash for
7 * safety reasons-- use <linux>/drivers/sbus/char/flash.c instead.
8 *
9 * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
10 *
11 */
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/fs.h>
16 #include <linux/errno.h>
17 #include <linux/init.h>
18 #include <linux/ioport.h>
19 #include <asm/ebus.h>
20 #include <asm/oplib.h>
21 #include <asm/prom.h>
22 #include <asm/uaccess.h>
23 #include <asm/io.h>
25 #include <linux/mtd/mtd.h>
26 #include <linux/mtd/map.h>
28 #define UFLASH_OBPNAME "flashprom"
29 #define UFLASH_DEVNAME "userflash"
31 #define UFLASH_WINDOW_SIZE 0x200000
32 #define UFLASH_BUSWIDTH 1 /* EBus is 8-bit */
34 MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
35 MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets");
36 MODULE_SUPPORTED_DEVICE("userflash");
37 MODULE_LICENSE("GPL");
38 MODULE_VERSION("2.0");
40 static LIST_HEAD(device_list);
41 struct uflash_dev {
42 char *name; /* device name */
43 struct map_info map; /* mtd map info */
44 struct mtd_info *mtd; /* mtd info */
45 };
48 struct map_info uflash_map_templ = {
49 .name = "SUNW,???-????",
50 .size = UFLASH_WINDOW_SIZE,
51 .bankwidth = UFLASH_BUSWIDTH,
52 };
54 int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp)
55 {
56 struct uflash_dev *up;
57 struct resource *res;
59 res = &edev->resource[0];
61 if (edev->num_addrs != 1) {
62 /* Non-CFI userflash device-- once I find one we
63 * can work on supporting it.
64 */
65 printk("%s: unsupported device at 0x%llx (%d regs): " \
66 "email ebrower@usa.net\n",
67 dp->full_name, (unsigned long long)res->start,
68 edev->num_addrs);
70 return -ENODEV;
71 }
73 up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL);
74 if (!up)
75 return -ENOMEM;
77 /* copy defaults and tweak parameters */
78 memcpy(&up->map, &uflash_map_templ, sizeof(uflash_map_templ));
79 up->map.size = (res->end - res->start) + 1UL;
81 up->name = of_get_property(dp, "model", NULL);
82 if (up->name && 0 < strlen(up->name))
83 up->map.name = up->name;
85 up->map.phys = res->start;
87 up->map.virt = ioremap_nocache(res->start, up->map.size);
88 if (!up->map.virt) {
89 printk("%s: Failed to map device.\n", dp->full_name);
90 kfree(up);
92 return -EINVAL;
93 }
95 simple_map_init(&up->map);
97 /* MTD registration */
98 up->mtd = do_map_probe("cfi_probe", &up->map);
99 if (!up->mtd) {
100 iounmap(up->map.virt);
101 kfree(up);
103 return -ENXIO;
104 }
106 up->mtd->owner = THIS_MODULE;
108 add_mtd_device(up->mtd);
110 dev_set_drvdata(&edev->ofdev.dev, up);
112 return 0;
113 }
115 static int __devinit uflash_probe(struct of_device *dev, const struct of_device_id *match)
116 {
117 struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
118 struct device_node *dp = dev->node;
120 if (of_find_property(dp, "user", NULL))
121 return -ENODEV;
123 return uflash_devinit(edev, dp);
124 }
126 static int __devexit uflash_remove(struct of_device *dev)
127 {
128 struct uflash_dev *up = dev_get_drvdata(&dev->dev);
130 if (up->mtd) {
131 del_mtd_device(up->mtd);
132 map_destroy(up->mtd);
133 }
134 if (up->map.virt) {
135 iounmap(up->map.virt);
136 up->map.virt = NULL;
137 }
139 kfree(up);
141 return 0;
142 }
144 static struct of_device_id uflash_match[] = {
145 {
146 .name = UFLASH_OBPNAME,
147 },
148 {},
149 };
151 MODULE_DEVICE_TABLE(of, uflash_match);
153 static struct of_platform_driver uflash_driver = {
154 .name = UFLASH_DEVNAME,
155 .match_table = uflash_match,
156 .probe = uflash_probe,
157 .remove = __devexit_p(uflash_remove),
158 };
160 static int __init uflash_init(void)
161 {
162 return of_register_driver(&uflash_driver, &ebus_bus_type);
163 }
165 static void __exit uflash_exit(void)
166 {
167 of_unregister_driver(&uflash_driver);
168 }
170 module_init(uflash_init);
171 module_exit(uflash_exit);