ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/cstm_mips_ixx.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 * $Id: cstm_mips_ixx.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 *
4 * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
5 * Config with both CFI and JEDEC device support.
6 *
7 * Basically physmap.c with the addition of partitions and
8 * an array of mapping info to accomodate more than one flash type per board.
9 *
10 * Copyright 2000 MontaVista Software Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
33 #include <linux/module.h>
34 #include <linux/types.h>
35 #include <linux/kernel.h>
36 #include <linux/init.h>
37 #include <asm/io.h>
38 #include <linux/mtd/mtd.h>
39 #include <linux/mtd/map.h>
40 #include <linux/mtd/partitions.h>
41 #include <linux/delay.h>
43 #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
44 #define CC_GCR 0xB4013818
45 #define CC_GPBCR 0xB401380A
46 #define CC_GPBDR 0xB4013808
47 #define CC_M68K_DEVICE 1
48 #define CC_M68K_FUNCTION 6
49 #define CC_CONFADDR 0xB8004000
50 #define CC_CONFDATA 0xB8004004
51 #define CC_FC_FCR 0xB8002004
52 #define CC_FC_DCR 0xB8002008
53 #define CC_GPACR 0xB4013802
54 #define CC_GPAICR 0xB4013804
55 #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
57 #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
58 void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
59 {
60 static DEFINE_SPINLOCK(vpp_lock);
61 static int vpp_count = 0;
62 unsigned long flags;
64 spin_lock_irqsave(&vpp_lock, flags);
66 if (vpp) {
67 if (!vpp_count++) {
68 __u16 data;
69 __u8 data1;
70 static u8 first = 1;
72 // Set GPIO port B pin3 to high
73 data = *(__u16 *)(CC_GPBCR);
74 data = (data & 0xff0f) | 0x0040;
75 *(__u16 *)CC_GPBCR = data;
76 *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) | 0x08;
77 if (first) {
78 first = 0;
79 /* need to have this delay for first
80 enabling vpp after powerup */
81 udelay(40);
82 }
83 }
84 } else {
85 if (!--vpp_count) {
86 __u16 data;
88 // Set GPIO port B pin3 to high
89 data = *(__u16 *)(CC_GPBCR);
90 data = (data & 0xff3f) | 0x0040;
91 *(__u16 *)CC_GPBCR = data;
92 *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7;
93 }
94 }
95 spin_unlock_irqrestore(&vpp_lock, flags);
96 }
97 #endif
99 /* board and partition description */
101 #define MAX_PHYSMAP_PARTITIONS 8
102 struct cstm_mips_ixx_info {
103 char *name;
104 unsigned long window_addr;
105 unsigned long window_size;
106 int bankwidth;
107 int num_partitions;
108 };
110 #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
111 #define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
112 const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
113 {
114 { // 28F128J3A in 2x16 configuration
115 "big flash", // name
116 0x08000000, // window_addr
117 0x02000000, // window_size
118 4, // bankwidth
119 1, // num_partitions
120 }
122 };
123 static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
124 { // 28F128J3A in 2x16 configuration
125 {
126 .name = "main partition ",
127 .size = 0x02000000, // 128 x 2 x 128k byte sectors
128 .offset = 0,
129 },
130 },
131 };
132 #else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
133 #define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
134 const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
135 {
136 {
137 "MTD flash", // name
138 CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr
139 CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size
140 CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH, // bankwidth
141 1, // num_partitions
142 },
144 };
145 static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
146 {
147 {
148 .name = "main partition",
149 .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN,
150 .offset = 0,
151 },
152 },
153 };
154 #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
156 struct map_info cstm_mips_ixx_map[PHYSMAP_NUMBER];
158 int __init init_cstm_mips_ixx(void)
159 {
160 int i;
161 int jedec;
162 struct mtd_info *mymtd;
163 struct mtd_partition *parts;
165 /* Initialize mapping */
166 for (i=0;i<PHYSMAP_NUMBER;i++) {
167 printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
168 cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
171 cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr;
172 cstm_mips_ixx_map[i].virt = ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);
173 if (!cstm_mips_ixx_map[i].virt) {
174 printk(KERN_WARNING "Failed to ioremap\n");
175 return -EIO;
176 }
177 cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name;
178 cstm_mips_ixx_map[i].size = cstm_mips_ixx_board_desc[i].window_size;
179 cstm_mips_ixx_map[i].bankwidth = cstm_mips_ixx_board_desc[i].bankwidth;
180 #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
181 cstm_mips_ixx_map[i].set_vpp = cstm_mips_ixx_set_vpp;
182 #endif
183 simple_map_init(&cstm_mips_ixx_map[i]);
184 //printk(KERN_NOTICE "cstm_mips_ixx: ioremap is %x\n",(unsigned int)(cstm_mips_ixx_map[i].virt));
185 }
187 #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
188 setup_ITE_IVR_flash();
189 #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
191 for (i=0;i<PHYSMAP_NUMBER;i++) {
192 parts = &cstm_mips_ixx_partitions[i][0];
193 jedec = 0;
194 mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &cstm_mips_ixx_map[i]);
195 //printk(KERN_NOTICE "phymap %d cfi_probe: mymtd is %x\n",i,(unsigned int)mymtd);
196 if (!mymtd) {
197 jedec = 1;
198 mymtd = (struct mtd_info *)do_map_probe("jedec", &cstm_mips_ixx_map[i]);
199 printk(KERN_NOTICE "cstm_mips_ixx %d jedec: mymtd is %x\n",i,(unsigned int)mymtd);
200 }
201 if (mymtd) {
202 mymtd->owner = THIS_MODULE;
204 cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd;
205 add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions);
206 }
207 else
208 return -ENXIO;
209 }
210 return 0;
211 }
213 static void __exit cleanup_cstm_mips_ixx(void)
214 {
215 int i;
216 struct mtd_info *mymtd;
218 for (i=0;i<PHYSMAP_NUMBER;i++) {
219 mymtd = (struct mtd_info *)cstm_mips_ixx_map[i].map_priv_2;
220 if (mymtd) {
221 del_mtd_partitions(mymtd);
222 map_destroy(mymtd);
223 }
224 if (cstm_mips_ixx_map[i].virt) {
225 iounmap((void *)cstm_mips_ixx_map[i].virt);
226 cstm_mips_ixx_map[i].virt = 0;
227 }
228 }
229 }
230 #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
231 void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32 data)
232 {
233 __u32 offset;
235 offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ;
237 *(__u32 *)CC_CONFADDR = offset;
238 *(__u32 *)CC_CONFDATA = data;
239 }
240 void setup_ITE_IVR_flash()
241 {
242 __u32 size, base;
244 size = 0x0e000000; // 32MiB
245 base = (0x08000000) >> 8 >>1; // Bug: we must shift one more bit
247 /* need to set ITE flash to 32 bits instead of default 8 */
248 #ifdef CONFIG_MIPS_IVR
249 *(__u32 *)CC_FC_FCR = 0x55;
250 *(__u32 *)CC_GPACR = 0xfffc;
251 #else
252 *(__u32 *)CC_FC_FCR = 0x77;
253 #endif
254 /* turn bursting off */
255 *(__u32 *)CC_FC_DCR = 0x0;
257 /* setup for one chip 4 byte PCI access */
258 PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x60, size | base);
259 PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x64, 0x02);
260 }
261 #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
263 module_init(init_cstm_mips_ixx);
264 module_exit(cleanup_cstm_mips_ixx);
267 MODULE_LICENSE("GPL");
268 MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
269 MODULE_DESCRIPTION("MTD map driver for ITE 8172G and Globespan IVR boards");