ia64/linux-2.6.18-xen.hg

view drivers/atm/nicstarmac.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 * this file included by nicstar.c
3 */
5 /*
6 * nicstarmac.c
7 * Read this ForeRunner's MAC address from eprom/eeprom
8 */
10 typedef void __iomem *virt_addr_t;
12 #define CYCLE_DELAY 5
14 /* This was the original definition
15 #define osp_MicroDelay(microsec) \
16 do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
17 */
18 #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
19 udelay((useconds));}
22 /* The following tables represent the timing diagrams found in
23 * the Data Sheet for the Xicor X25020 EEProm. The #defines below
24 * represent the bits in the NICStAR's General Purpose register
25 * that must be toggled for the corresponding actions on the EEProm
26 * to occur.
27 */
29 /* Write Data To EEProm from SI line on rising edge of CLK */
30 /* Read Data From EEProm on falling edge of CLK */
32 #define CS_HIGH 0x0002 /* Chip select high */
33 #define CS_LOW 0x0000 /* Chip select low (active low)*/
34 #define CLK_HIGH 0x0004 /* Clock high */
35 #define CLK_LOW 0x0000 /* Clock low */
36 #define SI_HIGH 0x0001 /* Serial input data high */
37 #define SI_LOW 0x0000 /* Serial input data low */
39 /* Read Status Register = 0000 0101b */
40 #if 0
41 static u_int32_t rdsrtab[] =
42 {
43 CS_HIGH | CLK_HIGH,
44 CS_LOW | CLK_LOW,
45 CLK_HIGH, /* 0 */
46 CLK_LOW,
47 CLK_HIGH, /* 0 */
48 CLK_LOW,
49 CLK_HIGH, /* 0 */
50 CLK_LOW,
51 CLK_HIGH, /* 0 */
52 CLK_LOW,
53 CLK_HIGH, /* 0 */
54 CLK_LOW | SI_HIGH,
55 CLK_HIGH | SI_HIGH, /* 1 */
56 CLK_LOW | SI_LOW,
57 CLK_HIGH, /* 0 */
58 CLK_LOW | SI_HIGH,
59 CLK_HIGH | SI_HIGH /* 1 */
60 };
61 #endif /* 0 */
64 /* Read from EEPROM = 0000 0011b */
65 static u_int32_t readtab[] =
66 {
67 /*
68 CS_HIGH | CLK_HIGH,
69 */
70 CS_LOW | CLK_LOW,
71 CLK_HIGH, /* 0 */
72 CLK_LOW,
73 CLK_HIGH, /* 0 */
74 CLK_LOW,
75 CLK_HIGH, /* 0 */
76 CLK_LOW,
77 CLK_HIGH, /* 0 */
78 CLK_LOW,
79 CLK_HIGH, /* 0 */
80 CLK_LOW,
81 CLK_HIGH, /* 0 */
82 CLK_LOW | SI_HIGH,
83 CLK_HIGH | SI_HIGH, /* 1 */
84 CLK_LOW | SI_HIGH,
85 CLK_HIGH | SI_HIGH /* 1 */
86 };
89 /* Clock to read from/write to the eeprom */
90 static u_int32_t clocktab[] =
91 {
92 CLK_LOW,
93 CLK_HIGH,
94 CLK_LOW,
95 CLK_HIGH,
96 CLK_LOW,
97 CLK_HIGH,
98 CLK_LOW,
99 CLK_HIGH,
100 CLK_LOW,
101 CLK_HIGH,
102 CLK_LOW,
103 CLK_HIGH,
104 CLK_LOW,
105 CLK_HIGH,
106 CLK_LOW,
107 CLK_HIGH,
108 CLK_LOW
109 };
112 #define NICSTAR_REG_WRITE(bs, reg, val) \
113 while ( readl(bs + STAT) & 0x0200 ) ; \
114 writel((val),(base)+(reg))
115 #define NICSTAR_REG_READ(bs, reg) \
116 readl((base)+(reg))
117 #define NICSTAR_REG_GENERAL_PURPOSE GP
119 /*
120 * This routine will clock the Read_Status_reg function into the X2520
121 * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose
122 * register.
123 */
124 #if 0
125 u_int32_t
126 nicstar_read_eprom_status( virt_addr_t base )
127 {
128 u_int32_t val;
129 u_int32_t rbyte;
130 int32_t i, j;
132 /* Send read instruction */
133 val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0;
135 for (i=0; i<sizeof rdsrtab/sizeof rdsrtab[0]; i++)
136 {
137 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
138 (val | rdsrtab[i]) );
139 osp_MicroDelay( CYCLE_DELAY );
140 }
142 /* Done sending instruction - now pull data off of bit 16, MSB first */
143 /* Data clocked out of eeprom on falling edge of clock */
145 rbyte = 0;
146 for (i=7, j=0; i>=0; i--)
147 {
148 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
149 (val | clocktab[j++]) );
150 rbyte |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE)
151 & 0x00010000) >> 16) << i);
152 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
153 (val | clocktab[j++]) );
154 osp_MicroDelay( CYCLE_DELAY );
155 }
156 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 );
157 osp_MicroDelay( CYCLE_DELAY );
158 return rbyte;
159 }
160 #endif /* 0 */
163 /*
164 * This routine will clock the Read_data function into the X2520
165 * eeprom, followed by the address to read from, through the NicSTaR's General
166 * Purpose register.
167 */
169 static u_int8_t
170 read_eprom_byte(virt_addr_t base, u_int8_t offset)
171 {
172 u_int32_t val = 0;
173 int i,j=0;
174 u_int8_t tempread = 0;
176 val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0;
178 /* Send READ instruction */
179 for (i=0; i<sizeof readtab/sizeof readtab[0]; i++)
180 {
181 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
182 (val | readtab[i]) );
183 osp_MicroDelay( CYCLE_DELAY );
184 }
186 /* Next, we need to send the byte address to read from */
187 for (i=7; i>=0; i--)
188 {
189 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
190 (val | clocktab[j++] | ((offset >> i) & 1) ) );
191 osp_MicroDelay(CYCLE_DELAY);
192 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
193 (val | clocktab[j++] | ((offset >> i) & 1) ) );
194 osp_MicroDelay( CYCLE_DELAY );
195 }
197 j = 0;
199 /* Now, we can read data from the eeprom by clocking it in */
200 for (i=7; i>=0; i--)
201 {
202 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
203 (val | clocktab[j++]) );
204 osp_MicroDelay( CYCLE_DELAY );
205 tempread |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE )
206 & 0x00010000) >> 16) << i);
207 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
208 (val | clocktab[j++]) );
209 osp_MicroDelay( CYCLE_DELAY );
210 }
212 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 );
213 osp_MicroDelay( CYCLE_DELAY );
214 return tempread;
215 }
218 static void
219 nicstar_init_eprom( virt_addr_t base )
220 {
221 u_int32_t val;
223 /*
224 * turn chip select off
225 */
226 val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
228 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
229 (val | CS_HIGH | CLK_HIGH));
230 osp_MicroDelay( CYCLE_DELAY );
232 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
233 (val | CS_HIGH | CLK_LOW));
234 osp_MicroDelay( CYCLE_DELAY );
236 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
237 (val | CS_HIGH | CLK_HIGH));
238 osp_MicroDelay( CYCLE_DELAY );
240 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
241 (val | CS_HIGH | CLK_LOW));
242 osp_MicroDelay( CYCLE_DELAY );
243 }
246 /*
247 * This routine will be the interface to the ReadPromByte function
248 * above.
249 */
251 static void
252 nicstar_read_eprom(
253 virt_addr_t base,
254 u_int8_t prom_offset,
255 u_int8_t *buffer,
256 u_int32_t nbytes )
257 {
258 u_int i;
260 for (i=0; i<nbytes; i++)
261 {
262 buffer[i] = read_eprom_byte( base, prom_offset );
263 ++prom_offset;
264 osp_MicroDelay( CYCLE_DELAY );
265 }
266 }
269 /*
270 void osp_MicroDelay(int x) {
272 }
273 */