ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/dc21285.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 * MTD map driver for flash on the DC21285 (the StrongARM-110 companion chip)
3 *
4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 *
6 * This code is GPL
7 *
8 * $Id: dc21285.c,v 1.24 2005/11/07 11:14:26 gleixner Exp $
9 */
10 #include <linux/module.h>
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/delay.h>
15 #include <linux/slab.h>
17 #include <linux/mtd/mtd.h>
18 #include <linux/mtd/map.h>
19 #include <linux/mtd/partitions.h>
21 #include <asm/io.h>
22 #include <asm/hardware/dec21285.h>
23 #include <asm/mach-types.h>
26 static struct mtd_info *dc21285_mtd;
28 #ifdef CONFIG_ARCH_NETWINDER
29 /*
30 * This is really ugly, but it seams to be the only
31 * realiable way to do it, as the cpld state machine
32 * is unpredictible. So we have a 25us penalty per
33 * write access.
34 */
35 static void nw_en_write(void)
36 {
37 extern spinlock_t gpio_lock;
38 unsigned long flags;
40 /*
41 * we want to write a bit pattern XXX1 to Xilinx to enable
42 * the write gate, which will be open for about the next 2ms.
43 */
44 spin_lock_irqsave(&gpio_lock, flags);
45 cpld_modify(1, 1);
46 spin_unlock_irqrestore(&gpio_lock, flags);
48 /*
49 * let the ISA bus to catch on...
50 */
51 udelay(25);
52 }
53 #else
54 #define nw_en_write() do { } while (0)
55 #endif
57 static map_word dc21285_read8(struct map_info *map, unsigned long ofs)
58 {
59 map_word val;
60 val.x[0] = *(uint8_t*)(map->virt + ofs);
61 return val;
62 }
64 static map_word dc21285_read16(struct map_info *map, unsigned long ofs)
65 {
66 map_word val;
67 val.x[0] = *(uint16_t*)(map->virt + ofs);
68 return val;
69 }
71 static map_word dc21285_read32(struct map_info *map, unsigned long ofs)
72 {
73 map_word val;
74 val.x[0] = *(uint32_t*)(map->virt + ofs);
75 return val;
76 }
78 static void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
79 {
80 memcpy(to, (void*)(map->virt + from), len);
81 }
83 static void dc21285_write8(struct map_info *map, const map_word d, unsigned long adr)
84 {
85 if (machine_is_netwinder())
86 nw_en_write();
87 *CSR_ROMWRITEREG = adr & 3;
88 adr &= ~3;
89 *(uint8_t*)(map->virt + adr) = d.x[0];
90 }
92 static void dc21285_write16(struct map_info *map, const map_word d, unsigned long adr)
93 {
94 if (machine_is_netwinder())
95 nw_en_write();
96 *CSR_ROMWRITEREG = adr & 3;
97 adr &= ~3;
98 *(uint16_t*)(map->virt + adr) = d.x[0];
99 }
101 static void dc21285_write32(struct map_info *map, const map_word d, unsigned long adr)
102 {
103 if (machine_is_netwinder())
104 nw_en_write();
105 *(uint32_t*)(map->virt + adr) = d.x[0];
106 }
108 static void dc21285_copy_to_32(struct map_info *map, unsigned long to, const void *from, ssize_t len)
109 {
110 while (len > 0) {
111 map_word d;
112 d.x[0] = *((uint32_t*)from);
113 dc21285_write32(map, d, to);
114 from += 4;
115 to += 4;
116 len -= 4;
117 }
118 }
120 static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const void *from, ssize_t len)
121 {
122 while (len > 0) {
123 map_word d;
124 d.x[0] = *((uint16_t*)from);
125 dc21285_write16(map, d, to);
126 from += 2;
127 to += 2;
128 len -= 2;
129 }
130 }
132 static void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len)
133 {
134 map_word d;
135 d.x[0] = *((uint8_t*)from);
136 dc21285_write8(map, d, to);
137 from++;
138 to++;
139 len--;
140 }
142 static struct map_info dc21285_map = {
143 .name = "DC21285 flash",
144 .phys = NO_XIP,
145 .size = 16*1024*1024,
146 .copy_from = dc21285_copy_from,
147 };
150 /* Partition stuff */
151 #ifdef CONFIG_MTD_PARTITIONS
152 static struct mtd_partition *dc21285_parts;
153 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
154 #endif
156 static int __init init_dc21285(void)
157 {
159 #ifdef CONFIG_MTD_PARTITIONS
160 int nrparts;
161 #endif
163 /* Determine bankwidth */
164 switch (*CSR_SA110_CNTL & (3<<14)) {
165 case SA110_CNTL_ROMWIDTH_8:
166 dc21285_map.bankwidth = 1;
167 dc21285_map.read = dc21285_read8;
168 dc21285_map.write = dc21285_write8;
169 dc21285_map.copy_to = dc21285_copy_to_8;
170 break;
171 case SA110_CNTL_ROMWIDTH_16:
172 dc21285_map.bankwidth = 2;
173 dc21285_map.read = dc21285_read16;
174 dc21285_map.write = dc21285_write16;
175 dc21285_map.copy_to = dc21285_copy_to_16;
176 break;
177 case SA110_CNTL_ROMWIDTH_32:
178 dc21285_map.bankwidth = 4;
179 dc21285_map.read = dc21285_read32;
180 dc21285_map.write = dc21285_write32;
181 dc21285_map.copy_to = dc21285_copy_to_32;
182 break;
183 default:
184 printk (KERN_ERR "DC21285 flash: undefined bankwidth\n");
185 return -ENXIO;
186 }
187 printk (KERN_NOTICE "DC21285 flash support (%d-bit bankwidth)\n",
188 dc21285_map.bankwidth*8);
190 /* Let's map the flash area */
191 dc21285_map.virt = ioremap(DC21285_FLASH, 16*1024*1024);
192 if (!dc21285_map.virt) {
193 printk("Failed to ioremap\n");
194 return -EIO;
195 }
197 if (machine_is_ebsa285()) {
198 dc21285_mtd = do_map_probe("cfi_probe", &dc21285_map);
199 } else {
200 dc21285_mtd = do_map_probe("jedec_probe", &dc21285_map);
201 }
203 if (!dc21285_mtd) {
204 iounmap(dc21285_map.virt);
205 return -ENXIO;
206 }
208 dc21285_mtd->owner = THIS_MODULE;
210 #ifdef CONFIG_MTD_PARTITIONS
211 nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
212 if (nrparts > 0)
213 add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts);
214 else
215 #endif
216 add_mtd_device(dc21285_mtd);
218 if(machine_is_ebsa285()) {
219 /*
220 * Flash timing is determined with bits 19-16 of the
221 * CSR_SA110_CNTL. The value is the number of wait cycles, or
222 * 0 for 16 cycles (the default). Cycles are 20 ns.
223 * Here we use 7 for 140 ns flash chips.
224 */
225 /* access time */
226 *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16));
227 /* burst time */
228 *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20));
229 /* tristate time */
230 *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
231 }
233 return 0;
234 }
236 static void __exit cleanup_dc21285(void)
237 {
238 #ifdef CONFIG_MTD_PARTITIONS
239 if (dc21285_parts) {
240 del_mtd_partitions(dc21285_mtd);
241 kfree(dc21285_parts);
242 } else
243 #endif
244 del_mtd_device(dc21285_mtd);
246 map_destroy(dc21285_mtd);
247 iounmap(dc21285_map.virt);
248 }
250 module_init(init_dc21285);
251 module_exit(cleanup_dc21285);
254 MODULE_LICENSE("GPL");
255 MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
256 MODULE_DESCRIPTION("MTD map driver for DC21285 boards");