ia64/linux-2.6.18-xen.hg

view arch/alpha/kernel/smc37c93x.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 * SMC 37C93X initialization code
3 */
5 #include <linux/kernel.h>
7 #include <linux/slab.h>
8 #include <linux/mm.h>
9 #include <linux/init.h>
10 #include <linux/delay.h>
12 #include <asm/hwrpb.h>
13 #include <asm/io.h>
14 #include <asm/segment.h>
16 #define SMC_DEBUG 0
18 #if SMC_DEBUG
19 # define DBG_DEVS(args) printk args
20 #else
21 # define DBG_DEVS(args)
22 #endif
24 #define KB 1024
25 #define MB (1024*KB)
26 #define GB (1024*MB)
28 /* device "activate" register contents */
29 #define DEVICE_ON 1
30 #define DEVICE_OFF 0
32 /* configuration on/off keys */
33 #define CONFIG_ON_KEY 0x55
34 #define CONFIG_OFF_KEY 0xaa
36 /* configuration space device definitions */
37 #define FDC 0
38 #define IDE1 1
39 #define IDE2 2
40 #define PARP 3
41 #define SER1 4
42 #define SER2 5
43 #define RTCL 6
44 #define KYBD 7
45 #define AUXIO 8
47 /* Chip register offsets from base */
48 #define CONFIG_CONTROL 0x02
49 #define INDEX_ADDRESS 0x03
50 #define LOGICAL_DEVICE_NUMBER 0x07
51 #define DEVICE_ID 0x20
52 #define DEVICE_REV 0x21
53 #define POWER_CONTROL 0x22
54 #define POWER_MGMT 0x23
55 #define OSC 0x24
57 #define ACTIVATE 0x30
58 #define ADDR_HI 0x60
59 #define ADDR_LO 0x61
60 #define INTERRUPT_SEL 0x70
61 #define INTERRUPT_SEL_2 0x72 /* KYBD/MOUS only */
62 #define DMA_CHANNEL_SEL 0x74 /* FDC/PARP only */
64 #define FDD_MODE_REGISTER 0x90
65 #define FDD_OPTION_REGISTER 0x91
67 /* values that we read back that are expected ... */
68 #define VALID_DEVICE_ID 2
70 /* default device addresses */
71 #define KYBD_INTERRUPT 1
72 #define MOUS_INTERRUPT 12
73 #define COM2_BASE 0x2f8
74 #define COM2_INTERRUPT 3
75 #define COM1_BASE 0x3f8
76 #define COM1_INTERRUPT 4
77 #define PARP_BASE 0x3bc
78 #define PARP_INTERRUPT 7
80 static unsigned long __init SMCConfigState(unsigned long baseAddr)
81 {
82 unsigned char devId;
83 unsigned char devRev;
85 unsigned long configPort;
86 unsigned long indexPort;
87 unsigned long dataPort;
89 int i;
91 configPort = indexPort = baseAddr;
92 dataPort = configPort + 1;
94 #define NUM_RETRIES 5
96 for (i = 0; i < NUM_RETRIES; i++)
97 {
98 outb(CONFIG_ON_KEY, configPort);
99 outb(CONFIG_ON_KEY, configPort);
100 outb(DEVICE_ID, indexPort);
101 devId = inb(dataPort);
102 if (devId == VALID_DEVICE_ID) {
103 outb(DEVICE_REV, indexPort);
104 devRev = inb(dataPort);
105 break;
106 }
107 else
108 udelay(100);
109 }
110 return (i != NUM_RETRIES) ? baseAddr : 0L;
111 }
113 static void __init SMCRunState(unsigned long baseAddr)
114 {
115 outb(CONFIG_OFF_KEY, baseAddr);
116 }
118 static unsigned long __init SMCDetectUltraIO(void)
119 {
120 unsigned long baseAddr;
122 baseAddr = 0x3F0;
123 if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x3F0 ) {
124 return( baseAddr );
125 }
126 baseAddr = 0x370;
127 if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x370 ) {
128 return( baseAddr );
129 }
130 return( ( unsigned long )0 );
131 }
133 static void __init SMCEnableDevice(unsigned long baseAddr,
134 unsigned long device,
135 unsigned long portaddr,
136 unsigned long interrupt)
137 {
138 unsigned long indexPort;
139 unsigned long dataPort;
141 indexPort = baseAddr;
142 dataPort = baseAddr + 1;
144 outb(LOGICAL_DEVICE_NUMBER, indexPort);
145 outb(device, dataPort);
147 outb(ADDR_LO, indexPort);
148 outb(( portaddr & 0xFF ), dataPort);
150 outb(ADDR_HI, indexPort);
151 outb((portaddr >> 8) & 0xFF, dataPort);
153 outb(INTERRUPT_SEL, indexPort);
154 outb(interrupt, dataPort);
156 outb(ACTIVATE, indexPort);
157 outb(DEVICE_ON, dataPort);
158 }
160 static void __init SMCEnableKYBD(unsigned long baseAddr)
161 {
162 unsigned long indexPort;
163 unsigned long dataPort;
165 indexPort = baseAddr;
166 dataPort = baseAddr + 1;
168 outb(LOGICAL_DEVICE_NUMBER, indexPort);
169 outb(KYBD, dataPort);
171 outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
172 outb(KYBD_INTERRUPT, dataPort);
174 outb(INTERRUPT_SEL_2, indexPort); /* Secondary interrupt select */
175 outb(MOUS_INTERRUPT, dataPort);
177 outb(ACTIVATE, indexPort);
178 outb(DEVICE_ON, dataPort);
179 }
181 static void __init SMCEnableFDC(unsigned long baseAddr)
182 {
183 unsigned long indexPort;
184 unsigned long dataPort;
186 unsigned char oldValue;
188 indexPort = baseAddr;
189 dataPort = baseAddr + 1;
191 outb(LOGICAL_DEVICE_NUMBER, indexPort);
192 outb(FDC, dataPort);
194 outb(FDD_MODE_REGISTER, indexPort);
195 oldValue = inb(dataPort);
197 oldValue |= 0x0E; /* Enable burst mode */
198 outb(oldValue, dataPort);
200 outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
201 outb(0x06, dataPort );
203 outb(DMA_CHANNEL_SEL, indexPort); /* DMA channel select */
204 outb(0x02, dataPort);
206 outb(ACTIVATE, indexPort);
207 outb(DEVICE_ON, dataPort);
208 }
210 #if SMC_DEBUG
211 static void __init SMCReportDeviceStatus(unsigned long baseAddr)
212 {
213 unsigned long indexPort;
214 unsigned long dataPort;
215 unsigned char currentControl;
217 indexPort = baseAddr;
218 dataPort = baseAddr + 1;
220 outb(POWER_CONTROL, indexPort);
221 currentControl = inb(dataPort);
223 printk(currentControl & (1 << FDC)
224 ? "\t+FDC Enabled\n" : "\t-FDC Disabled\n");
225 printk(currentControl & (1 << IDE1)
226 ? "\t+IDE1 Enabled\n" : "\t-IDE1 Disabled\n");
227 printk(currentControl & (1 << IDE2)
228 ? "\t+IDE2 Enabled\n" : "\t-IDE2 Disabled\n");
229 printk(currentControl & (1 << PARP)
230 ? "\t+PARP Enabled\n" : "\t-PARP Disabled\n");
231 printk(currentControl & (1 << SER1)
232 ? "\t+SER1 Enabled\n" : "\t-SER1 Disabled\n");
233 printk(currentControl & (1 << SER2)
234 ? "\t+SER2 Enabled\n" : "\t-SER2 Disabled\n");
236 printk( "\n" );
237 }
238 #endif
240 int __init SMC93x_Init(void)
241 {
242 unsigned long SMCUltraBase;
243 unsigned long flags;
245 local_irq_save(flags);
246 if ((SMCUltraBase = SMCDetectUltraIO()) != 0UL) {
247 #if SMC_DEBUG
248 SMCReportDeviceStatus(SMCUltraBase);
249 #endif
250 SMCEnableDevice(SMCUltraBase, SER1, COM1_BASE, COM1_INTERRUPT);
251 DBG_DEVS(("SMC FDC37C93X: SER1 done\n"));
252 SMCEnableDevice(SMCUltraBase, SER2, COM2_BASE, COM2_INTERRUPT);
253 DBG_DEVS(("SMC FDC37C93X: SER2 done\n"));
254 SMCEnableDevice(SMCUltraBase, PARP, PARP_BASE, PARP_INTERRUPT);
255 DBG_DEVS(("SMC FDC37C93X: PARP done\n"));
256 /* On PC164, IDE on the SMC is not enabled;
257 CMD646 (PCI) on MB */
258 SMCEnableKYBD(SMCUltraBase);
259 DBG_DEVS(("SMC FDC37C93X: KYB done\n"));
260 SMCEnableFDC(SMCUltraBase);
261 DBG_DEVS(("SMC FDC37C93X: FDC done\n"));
262 #if SMC_DEBUG
263 SMCReportDeviceStatus(SMCUltraBase);
264 #endif
265 SMCRunState(SMCUltraBase);
266 local_irq_restore(flags);
267 printk("SMC FDC37C93X Ultra I/O Controller found @ 0x%lx\n",
268 SMCUltraBase);
269 return 1;
270 }
271 else {
272 local_irq_restore(flags);
273 DBG_DEVS(("No SMC FDC37C93X Ultra I/O Controller found\n"));
274 return 0;
275 }
276 }