ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/scx200_docflash.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 /* linux/drivers/mtd/maps/scx200_docflash.c
3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
5 $Id: scx200_docflash.c,v 1.12 2005/11/07 11:14:28 gleixner Exp $
7 National Semiconductor SCx200 flash mapped with DOCCS
8 */
10 #include <linux/module.h>
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <asm/io.h>
15 #include <linux/mtd/mtd.h>
16 #include <linux/mtd/map.h>
17 #include <linux/mtd/partitions.h>
19 #include <linux/pci.h>
20 #include <linux/scx200.h>
22 #define NAME "scx200_docflash"
24 MODULE_AUTHOR("Christer Weinigel <wingel@hack.org>");
25 MODULE_DESCRIPTION("NatSemi SCx200 DOCCS Flash Driver");
26 MODULE_LICENSE("GPL");
28 static int probe = 0; /* Don't autoprobe */
29 static unsigned size = 0x1000000; /* 16 MiB the whole ISA address space */
30 static unsigned width = 8; /* Default to 8 bits wide */
31 static char *flashtype = "cfi_probe";
33 module_param(probe, int, 0);
34 MODULE_PARM_DESC(probe, "Probe for a BIOS mapping");
35 module_param(size, int, 0);
36 MODULE_PARM_DESC(size, "Size of the flash mapping");
37 module_param(width, int, 0);
38 MODULE_PARM_DESC(width, "Data width of the flash mapping (8/16)");
39 module_param(flashtype, charp, 0);
40 MODULE_PARM_DESC(flashtype, "Type of MTD probe to do");
42 static struct resource docmem = {
43 .flags = IORESOURCE_MEM,
44 .name = "NatSemi SCx200 DOCCS Flash",
45 };
47 static struct mtd_info *mymtd;
49 #ifdef CONFIG_MTD_PARTITIONS
50 static struct mtd_partition partition_info[] = {
51 {
52 .name = "DOCCS Boot kernel",
53 .offset = 0,
54 .size = 0xc0000
55 },
56 {
57 .name = "DOCCS Low BIOS",
58 .offset = 0xc0000,
59 .size = 0x40000
60 },
61 {
62 .name = "DOCCS File system",
63 .offset = 0x100000,
64 .size = ~0 /* calculate from flash size */
65 },
66 {
67 .name = "DOCCS High BIOS",
68 .offset = ~0, /* calculate from flash size */
69 .size = 0x80000
70 },
71 };
72 #define NUM_PARTITIONS ARRAY_SIZE(partition_info)
73 #endif
76 static struct map_info scx200_docflash_map = {
77 .name = "NatSemi SCx200 DOCCS Flash",
78 };
80 static int __init init_scx200_docflash(void)
81 {
82 unsigned u;
83 unsigned base;
84 unsigned ctrl;
85 unsigned pmr;
86 struct pci_dev *bridge;
88 printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n");
90 if ((bridge = pci_find_device(PCI_VENDOR_ID_NS,
91 PCI_DEVICE_ID_NS_SCx200_BRIDGE,
92 NULL)) == NULL)
93 return -ENODEV;
95 /* check that we have found the configuration block */
96 if (!scx200_cb_present())
97 return -ENODEV;
99 if (probe) {
100 /* Try to use the present flash mapping if any */
101 pci_read_config_dword(bridge, SCx200_DOCCS_BASE, &base);
102 pci_read_config_dword(bridge, SCx200_DOCCS_CTRL, &ctrl);
103 pmr = inl(scx200_cb_base + SCx200_PMR);
105 if (base == 0
106 || (ctrl & 0x07000000) != 0x07000000
107 || (ctrl & 0x0007ffff) == 0)
108 return -ENODEV;
110 size = ((ctrl&0x1fff)<<13) + (1<<13);
112 for (u = size; u > 1; u >>= 1)
113 ;
114 if (u != 1)
115 return -ENODEV;
117 if (pmr & (1<<6))
118 width = 16;
119 else
120 width = 8;
122 docmem.start = base;
123 docmem.end = base + size;
125 if (request_resource(&iomem_resource, &docmem)) {
126 printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n");
127 return -ENOMEM;
128 }
129 } else {
130 for (u = size; u > 1; u >>= 1)
131 ;
132 if (u != 1) {
133 printk(KERN_ERR NAME ": invalid size for flash mapping\n");
134 return -EINVAL;
135 }
137 if (width != 8 && width != 16) {
138 printk(KERN_ERR NAME ": invalid bus width for flash mapping\n");
139 return -EINVAL;
140 }
142 if (allocate_resource(&iomem_resource, &docmem,
143 size,
144 0xc0000000, 0xffffffff,
145 size, NULL, NULL)) {
146 printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n");
147 return -ENOMEM;
148 }
150 ctrl = 0x07000000 | ((size-1) >> 13);
152 printk(KERN_INFO "DOCCS BASE=0x%08lx, CTRL=0x%08lx\n", (long)docmem.start, (long)ctrl);
154 pci_write_config_dword(bridge, SCx200_DOCCS_BASE, docmem.start);
155 pci_write_config_dword(bridge, SCx200_DOCCS_CTRL, ctrl);
156 pmr = inl(scx200_cb_base + SCx200_PMR);
158 if (width == 8) {
159 pmr &= ~(1<<6);
160 } else {
161 pmr |= (1<<6);
162 }
163 outl(pmr, scx200_cb_base + SCx200_PMR);
164 }
166 printk(KERN_INFO NAME ": DOCCS mapped at 0x%llx-0x%llx, width %d\n",
167 (unsigned long long)docmem.start,
168 (unsigned long long)docmem.end, width);
170 scx200_docflash_map.size = size;
171 if (width == 8)
172 scx200_docflash_map.bankwidth = 1;
173 else
174 scx200_docflash_map.bankwidth = 2;
176 simple_map_init(&scx200_docflash_map);
178 scx200_docflash_map.phys = docmem.start;
179 scx200_docflash_map.virt = ioremap(docmem.start, scx200_docflash_map.size);
180 if (!scx200_docflash_map.virt) {
181 printk(KERN_ERR NAME ": failed to ioremap the flash\n");
182 release_resource(&docmem);
183 return -EIO;
184 }
186 mymtd = do_map_probe(flashtype, &scx200_docflash_map);
187 if (!mymtd) {
188 printk(KERN_ERR NAME ": unable to detect flash\n");
189 iounmap(scx200_docflash_map.virt);
190 release_resource(&docmem);
191 return -ENXIO;
192 }
194 if (size < mymtd->size)
195 printk(KERN_WARNING NAME ": warning, flash mapping is smaller than flash size\n");
197 mymtd->owner = THIS_MODULE;
199 #ifdef CONFIG_MTD_PARTITIONS
200 partition_info[3].offset = mymtd->size-partition_info[3].size;
201 partition_info[2].size = partition_info[3].offset-partition_info[2].offset;
202 add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
203 #else
204 add_mtd_device(mymtd);
205 #endif
206 return 0;
207 }
209 static void __exit cleanup_scx200_docflash(void)
210 {
211 if (mymtd) {
212 #ifdef CONFIG_MTD_PARTITIONS
213 del_mtd_partitions(mymtd);
214 #else
215 del_mtd_device(mymtd);
216 #endif
217 map_destroy(mymtd);
218 }
219 if (scx200_docflash_map.virt) {
220 iounmap(scx200_docflash_map.virt);
221 release_resource(&docmem);
222 }
223 }
225 module_init(init_scx200_docflash);
226 module_exit(cleanup_scx200_docflash);
228 /*
229 Local variables:
230 compile-command: "make -k -C ../../.. SUBDIRS=drivers/mtd/maps modules"
231 c-basic-offset: 8
232 End:
233 */