ia64/linux-2.6.18-xen.hg

view arch/mips/sgi-ip27/ip27-timer.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 * Copytight (C) 1999, 2000, 05, 06 Ralf Baechle (ralf@linux-mips.org)
3 * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
4 */
5 #include <linux/bcd.h>
6 #include <linux/init.h>
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/interrupt.h>
10 #include <linux/kernel_stat.h>
11 #include <linux/param.h>
12 #include <linux/time.h>
13 #include <linux/timex.h>
14 #include <linux/mm.h>
16 #include <asm/time.h>
17 #include <asm/pgtable.h>
18 #include <asm/sgialib.h>
19 #include <asm/sn/ioc3.h>
20 #include <asm/m48t35.h>
21 #include <asm/sn/klconfig.h>
22 #include <asm/sn/arch.h>
23 #include <asm/sn/addrs.h>
24 #include <asm/sn/sn_private.h>
25 #include <asm/sn/sn0/ip27.h>
26 #include <asm/sn/sn0/hub.h>
28 /*
29 * This is a hack; we really need to figure these values out dynamically
30 *
31 * Since 800 ns works very well with various HUB frequencies, such as
32 * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
33 *
34 * Ralf: which clock rate is used to feed the counter?
35 */
36 #define NSEC_PER_CYCLE 800
37 #define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE)
38 #define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ)
40 #define TICK_SIZE (tick_nsec / 1000)
42 static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */
43 static long last_rtc_update; /* Last time the rtc clock got updated */
45 extern volatile unsigned long wall_jiffies;
47 #if 0
48 static int set_rtc_mmss(unsigned long nowtime)
49 {
50 int retval = 0;
51 int real_seconds, real_minutes, cmos_minutes;
52 struct m48t35_rtc *rtc;
53 nasid_t nid;
55 nid = get_nasid();
56 rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
57 IOC3_BYTEBUS_DEV0);
59 rtc->control |= M48T35_RTC_READ;
60 cmos_minutes = BCD2BIN(rtc->min);
61 rtc->control &= ~M48T35_RTC_READ;
63 /*
64 * Since we're only adjusting minutes and seconds, don't interfere with
65 * hour overflow. This avoids messing with unknown time zones but
66 * requires your RTC not to be off by more than 15 minutes
67 */
68 real_seconds = nowtime % 60;
69 real_minutes = nowtime / 60;
70 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
71 real_minutes += 30; /* correct for half hour time zone */
72 real_minutes %= 60;
74 if (abs(real_minutes - cmos_minutes) < 30) {
75 real_seconds = BIN2BCD(real_seconds);
76 real_minutes = BIN2BCD(real_minutes);
77 rtc->control |= M48T35_RTC_SET;
78 rtc->sec = real_seconds;
79 rtc->min = real_minutes;
80 rtc->control &= ~M48T35_RTC_SET;
81 } else {
82 printk(KERN_WARNING
83 "set_rtc_mmss: can't update from %d to %d\n",
84 cmos_minutes, real_minutes);
85 retval = -1;
86 }
88 return retval;
89 }
90 #endif
92 static unsigned int rt_timer_irq;
94 void ip27_rt_timer_interrupt(struct pt_regs *regs)
95 {
96 int cpu = smp_processor_id();
97 int cpuA = cputoslice(cpu) == 0;
98 unsigned int irq = rt_timer_irq;
100 irq_enter();
101 write_seqlock(&xtime_lock);
103 again:
104 LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */
105 ct_cur[cpu] += CYCLES_PER_JIFFY;
106 LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
108 if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
109 goto again;
111 kstat_this_cpu.irqs[irq]++; /* kstat only for bootcpu? */
113 if (cpu == 0)
114 do_timer(regs);
116 update_process_times(user_mode(regs));
118 /*
119 * If we have an externally synchronized Linux clock, then update
120 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
121 * called as close as possible to when a second starts.
122 */
123 if (ntp_synced() &&
124 xtime.tv_sec > last_rtc_update + 660 &&
125 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
126 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
127 if (rtc_mips_set_time(xtime.tv_sec) == 0) {
128 last_rtc_update = xtime.tv_sec;
129 } else {
130 last_rtc_update = xtime.tv_sec - 600;
131 /* do it again in 60 s */
132 }
133 }
135 write_sequnlock(&xtime_lock);
136 irq_exit();
137 }
139 unsigned long ip27_do_gettimeoffset(void)
140 {
141 unsigned long ct_cur1;
142 ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
143 return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
144 }
146 /* Includes for ioc3_init(). */
147 #include <asm/sn/types.h>
148 #include <asm/sn/sn0/addrs.h>
149 #include <asm/sn/sn0/hubni.h>
150 #include <asm/sn/sn0/hubio.h>
151 #include <asm/pci/bridge.h>
153 static __init unsigned long get_m48t35_time(void)
154 {
155 unsigned int year, month, date, hour, min, sec;
156 struct m48t35_rtc *rtc;
157 nasid_t nid;
159 nid = get_nasid();
160 rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
161 IOC3_BYTEBUS_DEV0);
163 rtc->control |= M48T35_RTC_READ;
164 sec = rtc->sec;
165 min = rtc->min;
166 hour = rtc->hour;
167 date = rtc->date;
168 month = rtc->month;
169 year = rtc->year;
170 rtc->control &= ~M48T35_RTC_READ;
172 sec = BCD2BIN(sec);
173 min = BCD2BIN(min);
174 hour = BCD2BIN(hour);
175 date = BCD2BIN(date);
176 month = BCD2BIN(month);
177 year = BCD2BIN(year);
179 year += 1970;
181 return mktime(year, month, date, hour, min, sec);
182 }
184 static unsigned int startup_rt_irq(unsigned int irq)
185 {
186 return 0;
187 }
189 static void shutdown_rt_irq(unsigned int irq)
190 {
191 }
193 static void enable_rt_irq(unsigned int irq)
194 {
195 }
197 static void disable_rt_irq(unsigned int irq)
198 {
199 }
201 static void mask_and_ack_rt(unsigned int irq)
202 {
203 }
205 static void end_rt_irq(unsigned int irq)
206 {
207 }
209 static struct irq_chip rt_irq_type = {
210 .typename = "SN HUB RT timer",
211 .startup = startup_rt_irq,
212 .shutdown = shutdown_rt_irq,
213 .enable = enable_rt_irq,
214 .disable = disable_rt_irq,
215 .ack = mask_and_ack_rt,
216 .end = end_rt_irq,
217 };
219 static struct irqaction rt_irqaction = {
220 .handler = ip27_rt_timer_interrupt,
221 .flags = IRQF_DISABLED,
222 .mask = CPU_MASK_NONE,
223 .name = "timer"
224 };
226 extern int allocate_irqno(void);
228 void __init plat_timer_setup(struct irqaction *irq)
229 {
230 int irqno = allocate_irqno();
232 if (irqno < 0)
233 panic("Can't allocate interrupt number for timer interrupt");
235 irq_desc[irqno].status = IRQ_DISABLED;
236 irq_desc[irqno].action = NULL;
237 irq_desc[irqno].depth = 1;
238 irq_desc[irqno].chip = &rt_irq_type;
240 /* over-write the handler, we use our own way */
241 irq->handler = no_action;
243 /* setup irqaction */
244 irq_desc[irqno].status |= IRQ_PER_CPU;
246 rt_timer_irq = irqno;
247 /*
248 * Only needed to get /proc/interrupt to display timer irq stats
249 */
250 setup_irq(irqno, &rt_irqaction);
251 }
253 void __init ip27_time_init(void)
254 {
255 xtime.tv_sec = get_m48t35_time();
256 xtime.tv_nsec = 0;
258 do_gettimeoffset = ip27_do_gettimeoffset;
259 }
261 void __init cpu_time_init(void)
262 {
263 lboard_t *board;
264 klcpu_t *cpu;
265 int cpuid;
267 /* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */
268 board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
269 if (!board)
270 panic("Can't find board info for myself.");
272 cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
273 cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
274 if (!cpu)
275 panic("No information about myself?");
277 printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
279 set_c0_status(SRB_TIMOCLK);
280 }
282 void __init hub_rtc_init(cnodeid_t cnode)
283 {
284 /*
285 * We only need to initialize the current node.
286 * If this is not the current node then it is a cpuless
287 * node and timeouts will not happen there.
288 */
289 if (get_compact_nodeid() == cnode) {
290 int cpu = smp_processor_id();
291 LOCAL_HUB_S(PI_RT_EN_A, 1);
292 LOCAL_HUB_S(PI_RT_EN_B, 1);
293 LOCAL_HUB_S(PI_PROF_EN_A, 0);
294 LOCAL_HUB_S(PI_PROF_EN_B, 0);
295 ct_cur[cpu] = CYCLES_PER_JIFFY;
296 LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
297 LOCAL_HUB_S(PI_RT_COUNT, 0);
298 LOCAL_HUB_S(PI_RT_PEND_A, 0);
299 LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
300 LOCAL_HUB_S(PI_RT_COUNT, 0);
301 LOCAL_HUB_S(PI_RT_PEND_B, 0);
302 }
303 }