ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/fortunet.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 /* fortunet.c memory map
2 *
3 * $Id: fortunet.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
4 */
6 #include <linux/module.h>
7 #include <linux/types.h>
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/string.h>
12 #include <linux/mtd/mtd.h>
13 #include <linux/mtd/map.h>
14 #include <linux/mtd/partitions.h>
16 #include <asm/io.h>
18 #define MAX_NUM_REGIONS 4
19 #define MAX_NUM_PARTITIONS 8
21 #define DEF_WINDOW_ADDR_PHY 0x00000000
22 #define DEF_WINDOW_SIZE 0x00800000 // 8 Mega Bytes
24 #define MTD_FORTUNET_PK "MTD FortuNet: "
26 #define MAX_NAME_SIZE 128
28 struct map_region
29 {
30 int window_addr_physical;
31 int altbankwidth;
32 struct map_info map_info;
33 struct mtd_info *mymtd;
34 struct mtd_partition parts[MAX_NUM_PARTITIONS];
35 char map_name[MAX_NAME_SIZE];
36 char parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE];
37 };
39 static struct map_region map_regions[MAX_NUM_REGIONS];
40 static int map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0};
41 static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0};
45 struct map_info default_map = {
46 .size = DEF_WINDOW_SIZE,
47 .bankwidth = 4,
48 };
50 static char * __init get_string_option(char *dest,int dest_size,char *sor)
51 {
52 if(!dest_size)
53 return sor;
54 dest_size--;
55 while(*sor)
56 {
57 if(*sor==',')
58 {
59 sor++;
60 break;
61 }
62 else if(*sor=='\"')
63 {
64 sor++;
65 while(*sor)
66 {
67 if(*sor=='\"')
68 {
69 sor++;
70 break;
71 }
72 *dest = *sor;
73 dest++;
74 sor++;
75 dest_size--;
76 if(!dest_size)
77 {
78 *dest = 0;
79 return sor;
80 }
81 }
82 }
83 else
84 {
85 *dest = *sor;
86 dest++;
87 sor++;
88 dest_size--;
89 if(!dest_size)
90 {
91 *dest = 0;
92 return sor;
93 }
94 }
95 }
96 *dest = 0;
97 return sor;
98 }
100 static int __init MTD_New_Region(char *line)
101 {
102 char string[MAX_NAME_SIZE];
103 int params[6];
104 get_options (get_string_option(string,sizeof(string),line),6,params);
105 if(params[0]<1)
106 {
107 printk(MTD_FORTUNET_PK "Bad parameters for MTD Region "
108 " name,region-number[,base,size,bankwidth,altbankwidth]\n");
109 return 1;
110 }
111 if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
112 {
113 printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
114 params[1],MAX_NUM_REGIONS-1);
115 return 1;
116 }
117 memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]]));
118 memcpy(&map_regions[params[1]].map_info,
119 &default_map,sizeof(map_regions[params[1]].map_info));
120 map_regions_set[params[1]] = 1;
121 map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY;
122 map_regions[params[1]].altbankwidth = 2;
123 map_regions[params[1]].mymtd = NULL;
124 map_regions[params[1]].map_info.name = map_regions[params[1]].map_name;
125 strcpy(map_regions[params[1]].map_info.name,string);
126 if(params[0]>1)
127 {
128 map_regions[params[1]].window_addr_physical = params[2];
129 }
130 if(params[0]>2)
131 {
132 map_regions[params[1]].map_info.size = params[3];
133 }
134 if(params[0]>3)
135 {
136 map_regions[params[1]].map_info.bankwidth = params[4];
137 }
138 if(params[0]>4)
139 {
140 map_regions[params[1]].altbankwidth = params[5];
141 }
142 return 1;
143 }
145 static int __init MTD_New_Partition(char *line)
146 {
147 char string[MAX_NAME_SIZE];
148 int params[4];
149 get_options (get_string_option(string,sizeof(string),line),4,params);
150 if(params[0]<3)
151 {
152 printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition "
153 " name,region-number,size,offset\n");
154 return 1;
155 }
156 if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
157 {
158 printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
159 params[1],MAX_NUM_REGIONS-1);
160 return 1;
161 }
162 if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
163 {
164 printk(MTD_FORTUNET_PK "Out of space for partition in this region\n");
165 return 1;
166 }
167 map_regions[params[1]].parts[map_regions_parts[params[1]]].name =
168 map_regions[params[1]]. parts_name[map_regions_parts[params[1]]];
169 strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string);
170 map_regions[params[1]].parts[map_regions_parts[params[1]]].size =
171 params[2];
172 map_regions[params[1]].parts[map_regions_parts[params[1]]].offset =
173 params[3];
174 map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0;
175 map_regions_parts[params[1]]++;
176 return 1;
177 }
179 __setup("MTD_Region=", MTD_New_Region);
180 __setup("MTD_Partition=", MTD_New_Partition);
182 /* Backwards-spelling-compatibility */
183 __setup("MTD_Partion=", MTD_New_Partition);
185 int __init init_fortunet(void)
186 {
187 int ix,iy;
188 for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++)
189 {
190 if(map_regions_parts[ix]&&(!map_regions_set[ix]))
191 {
192 printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n",
193 ix);
194 memset(&map_regions[ix],0,sizeof(map_regions[ix]));
195 memcpy(&map_regions[ix].map_info,&default_map,
196 sizeof(map_regions[ix].map_info));
197 map_regions_set[ix] = 1;
198 map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY;
199 map_regions[ix].altbankwidth = 2;
200 map_regions[ix].mymtd = NULL;
201 map_regions[ix].map_info.name = map_regions[ix].map_name;
202 strcpy(map_regions[ix].map_info.name,"FORTUNET");
203 }
204 if(map_regions_set[ix])
205 {
206 iy++;
207 printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically "
208 " address %x size %x\n",
209 map_regions[ix].map_info.name,
210 map_regions[ix].window_addr_physical,
211 map_regions[ix].map_info.size);
213 map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
215 map_regions[ix].map_info.virt =
216 ioremap_nocache(
217 map_regions[ix].window_addr_physical,
218 map_regions[ix].map_info.size);
219 if(!map_regions[ix].map_info.virt)
220 {
221 printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
222 map_regions[ix].map_info.name);
223 return -ENXIO;
224 }
225 simple_map_init(&map_regions[ix].map_info);
227 printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n",
228 map_regions[ix].map_info.name,
229 map_regions[ix].map_info.virt);
230 map_regions[ix].mymtd = do_map_probe("cfi_probe",
231 &map_regions[ix].map_info);
232 if((!map_regions[ix].mymtd)&&(
233 map_regions[ix].altbankwidth!=map_regions[ix].map_info.bankwidth))
234 {
235 printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate bankwidth "
236 "for %s flash.\n",
237 map_regions[ix].map_info.name);
238 map_regions[ix].map_info.bankwidth =
239 map_regions[ix].altbankwidth;
240 map_regions[ix].mymtd = do_map_probe("cfi_probe",
241 &map_regions[ix].map_info);
242 }
243 map_regions[ix].mymtd->owner = THIS_MODULE;
244 add_mtd_partitions(map_regions[ix].mymtd,
245 map_regions[ix].parts,map_regions_parts[ix]);
246 }
247 }
248 if(iy)
249 return 0;
250 return -ENXIO;
251 }
253 static void __exit cleanup_fortunet(void)
254 {
255 int ix;
256 for(ix=0;ix<MAX_NUM_REGIONS;ix++)
257 {
258 if(map_regions_set[ix])
259 {
260 if( map_regions[ix].mymtd )
261 {
262 del_mtd_partitions( map_regions[ix].mymtd );
263 map_destroy( map_regions[ix].mymtd );
264 }
265 iounmap((void *)map_regions[ix].map_info.virt);
266 }
267 }
268 }
270 module_init(init_fortunet);
271 module_exit(cleanup_fortunet);
273 MODULE_AUTHOR("FortuNet, Inc.");
274 MODULE_DESCRIPTION("MTD map driver for FortuNet boards");