ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/tqm834x.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 * drivers/mtd/maps/tqm834x.c
3 *
4 * MTD mapping driver for TQM834x boards
5 *
6 * Copyright 2005 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 *
12 */
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/slab.h>
19 #include <asm/io.h>
20 #include <asm/ppcboot.h>
22 #include <linux/mtd/mtd.h>
23 #include <linux/mtd/map.h>
24 #include <linux/mtd/partitions.h>
26 #define FLASH_BANK_MAX 2
28 extern unsigned char __res[];
30 /* trivial struct to describe partition information */
31 struct mtd_part_def
32 {
33 int nums;
34 unsigned char *type;
35 struct mtd_partition* mtd_part;
36 };
38 static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
39 static struct map_info* map_banks[FLASH_BANK_MAX];
40 static struct mtd_part_def part_banks[FLASH_BANK_MAX];
42 static unsigned long num_banks;
43 static unsigned long start_scan_addr;
45 #ifdef CONFIG_MTD_PARTITIONS
46 /*
47 * The following defines the partition layout of TQM834x boards.
48 *
49 * See include/linux/mtd/partitions.h for definition of the
50 * mtd_partition structure.
51 *
52 * Assume minimal initial size of 4 MiB per bank, will be updated
53 * later in init_tqm834x_mtd() routine.
54 */
56 /* Partition definition for the first flash bank which is always present. */
57 static struct mtd_partition tqm834x_partitions_bank1[] = {
58 {
59 .name = "u-boot", /* u-boot firmware */
60 .offset = 0x00000000,
61 .size = 0x00040000, /* 256 KiB */
62 /*mask_flags: MTD_WRITEABLE, * force read-only */
63 },
64 {
65 .name = "env", /* u-boot environment */
66 .offset = 0x00040000,
67 .size = 0x00020000, /* 128 KiB */
68 /*mask_flags: MTD_WRITEABLE, * force read-only */
69 },
70 {
71 .name = "kernel", /* linux kernel image */
72 .offset = 0x00060000,
73 .size = 0x00100000, /* 1 MiB */
74 /*mask_flags: MTD_WRITEABLE, * force read-only */
75 },
76 {
77 .name = "initrd", /* ramdisk image */
78 .offset = 0x00160000,
79 .size = 0x00200000, /* 2 MiB */
80 },
81 {
82 .name = "user", /* user data */
83 .offset = 0x00360000,
84 .size = 0x000a0000, /* remaining space */
85 /* NOTE: this parttion size is re-calcated in */
86 /* init_tqm834x_mtd() to cover actual remaining space. */
87 },
88 };
90 /* Partition definition for the second flash bank which may be present on some
91 * TQM834x boards.
92 */
93 static struct mtd_partition tqm834x_partitions_bank2[] = {
94 {
95 .name = "jffs2", /* jffs2 filesystem */
96 .offset = 0x00000000,
97 .size = 0x00400000, /* whole device */
98 /* NOTE: this parttion size is re-calcated in */
99 /* init_tqm834x_mtd() to cover actual device size. */
100 },
101 };
103 #endif /* CONFIG_MTD_PARTITIONS */
105 static int __init init_tqm834x_mtd(void)
106 {
107 int idx = 0, ret = 0;
108 unsigned long flash_addr, flash_size, mtd_size = 0;
110 /* pointer to TQM834x board info data */
111 bd_t *bd = (bd_t *)__res;
112 #ifdef CONFIG_MTD_CMDLINE_PARTS
113 int n;
114 char mtdid[4];
115 const char *part_probes[] = { "cmdlinepart", NULL };
116 #endif
118 flash_addr = bd->bi_flashstart;
119 flash_size = bd->bi_flashsize;
121 /* request maximum flash size address space */
122 start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
123 if (!start_scan_addr) {
124 printk("%s: Failed to ioremap address: 0x%lx\n",
125 __FUNCTION__, flash_addr);
126 return -EIO;
127 }
129 for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
130 if (mtd_size >= flash_size)
131 break;
133 pr_debug("%s: chip probing count %d\n", __FUNCTION__, idx);
135 map_banks[idx] =
136 (struct map_info *)kmalloc(sizeof(struct map_info),
137 GFP_KERNEL);
138 if (map_banks[idx] == NULL) {
139 ret = -ENOMEM;
140 goto error_mem;
141 }
142 memset((void *)map_banks[idx], 0, sizeof(struct map_info));
143 map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
144 if (map_banks[idx]->name == NULL) {
145 ret = -ENOMEM;
146 goto error_mem;
147 }
148 memset((void *)map_banks[idx]->name, 0, 16);
150 sprintf(map_banks[idx]->name, "TQM834x-%d", idx);
151 map_banks[idx]->size = flash_size;
152 map_banks[idx]->bankwidth = 4;
154 simple_map_init(map_banks[idx]);
156 map_banks[idx]->virt = (void __iomem *)
157 (start_scan_addr + ((idx > 0) ?
158 (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0));
159 map_banks[idx]->phys =
160 flash_addr + ((idx > 0) ?
161 (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
163 /* start to probe flash chips */
164 mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
165 if (mtd_banks[idx]) {
166 mtd_banks[idx]->owner = THIS_MODULE;
167 mtd_size += mtd_banks[idx]->size;
168 num_banks++;
169 pr_debug("%s: bank %ld, name: %s, size: %d bytes \n",
170 __FUNCTION__, num_banks,
171 mtd_banks[idx]->name, mtd_banks[idx]->size);
172 }
173 }
175 /* no supported flash chips found */
176 if (!num_banks) {
177 printk("TQM834x: No supported flash chips found!\n");
178 ret = -ENXIO;
179 goto error_mem;
180 }
182 #ifdef CONFIG_MTD_PARTITIONS
183 /*
184 * Select static partition definitions
185 */
186 n = ARRAY_SIZE(tqm834x_partitions_bank1);
187 part_banks[0].mtd_part = tqm834x_partitions_bank1;
188 part_banks[0].type = "static image bank1";
189 part_banks[0].nums = n;
191 /* update last partition size to cover actual remaining space */
192 tqm834x_partitions_bank1[n - 1].size =
193 mtd_banks[0]->size -
194 tqm834x_partitions_bank1[n - 1].offset;
196 /* check if we have second bank? */
197 if (num_banks == 2) {
198 n = ARRAY_SIZE(tqm834x_partitions_bank2);
199 part_banks[1].mtd_part = tqm834x_partitions_bank2;
200 part_banks[1].type = "static image bank2";
201 part_banks[1].nums = n;
203 /* update last partition size to cover actual remaining space */
204 tqm834x_partitions_bank2[n - 1].size =
205 mtd_banks[1]->size -
206 tqm834x_partitions_bank2[n - 1].offset;
207 }
209 for(idx = 0; idx < num_banks ; idx++) {
210 #ifdef CONFIG_MTD_CMDLINE_PARTS
211 sprintf(mtdid, "%d", idx);
212 n = parse_mtd_partitions(mtd_banks[idx],
213 part_probes,
214 &part_banks[idx].mtd_part,
215 0);
216 pr_debug("%s: %d command line partitions on bank %s\n",
217 __FUNCTION__, n, mtdid);
218 if (n > 0) {
219 part_banks[idx].type = "command line";
220 part_banks[idx].nums = n;
221 }
222 #endif /* CONFIG_MTD_CMDLINE_PARTS */
223 if (part_banks[idx].nums == 0) {
224 printk(KERN_NOTICE
225 "TQM834x flash bank %d: no partition info "
226 "available, registering whole device\n", idx);
227 add_mtd_device(mtd_banks[idx]);
228 } else {
229 printk(KERN_NOTICE
230 "TQM834x flash bank %d: Using %s partition "
231 "definition\n", idx, part_banks[idx].type);
232 add_mtd_partitions(mtd_banks[idx],
233 part_banks[idx].mtd_part,
234 part_banks[idx].nums);
235 }
236 }
237 #else /* ! CONFIG_MTD_PARTITIONS */
238 printk(KERN_NOTICE "TQM834x flash: registering %d flash banks "
239 "at once\n", num_banks);
241 for(idx = 0 ; idx < num_banks ; idx++)
242 add_mtd_device(mtd_banks[idx]);
244 #endif /* CONFIG_MTD_PARTITIONS */
246 return 0;
247 error_mem:
248 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
249 if (map_banks[idx] != NULL) {
250 if (map_banks[idx]->name != NULL) {
251 kfree(map_banks[idx]->name);
252 map_banks[idx]->name = NULL;
253 }
254 kfree(map_banks[idx]);
255 map_banks[idx] = NULL;
256 }
257 }
259 iounmap((void *)start_scan_addr);
261 return ret;
262 }
264 static void __exit cleanup_tqm834x_mtd(void)
265 {
266 unsigned int idx = 0;
267 for(idx = 0 ; idx < num_banks ; idx++) {
268 /* destroy mtd_info previously allocated */
269 if (mtd_banks[idx]) {
270 del_mtd_partitions(mtd_banks[idx]);
271 map_destroy(mtd_banks[idx]);
272 }
274 /* release map_info not used anymore */
275 kfree(map_banks[idx]->name);
276 kfree(map_banks[idx]);
277 }
279 if (start_scan_addr) {
280 iounmap((void *)start_scan_addr);
281 start_scan_addr = 0;
282 }
283 }
285 module_init(init_tqm834x_mtd);
286 module_exit(cleanup_tqm834x_mtd);
288 MODULE_LICENSE("GPL");
289 MODULE_AUTHOR("Wolfgang Denk <wd@denx.de>");
290 MODULE_DESCRIPTION("MTD map driver for TQM834x boards");