ia64/linux-2.6.18-xen.hg

annotate arch/mips/sgi-ip32/ip32-setup.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
rev   line source
ian@0 1 /*
ian@0 2 * IP32 basic setup
ian@0 3 *
ian@0 4 * This file is subject to the terms and conditions of the GNU General Public
ian@0 5 * License. See the file "COPYING" in the main directory of this archive
ian@0 6 * for more details.
ian@0 7 *
ian@0 8 * Copyright (C) 2000 Harald Koerfgen
ian@0 9 * Copyright (C) 2002, 2003, 2005 Ilya A. Volynets
ian@0 10 * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
ian@0 11 */
ian@0 12 #include <linux/console.h>
ian@0 13 #include <linux/init.h>
ian@0 14 #include <linux/interrupt.h>
ian@0 15 #include <linux/mc146818rtc.h>
ian@0 16 #include <linux/param.h>
ian@0 17 #include <linux/sched.h>
ian@0 18
ian@0 19 #include <asm/bootinfo.h>
ian@0 20 #include <asm/mc146818-time.h>
ian@0 21 #include <asm/mipsregs.h>
ian@0 22 #include <asm/mmu_context.h>
ian@0 23 #include <asm/sgialib.h>
ian@0 24 #include <asm/time.h>
ian@0 25 #include <asm/traps.h>
ian@0 26 #include <asm/io.h>
ian@0 27 #include <asm/ip32/crime.h>
ian@0 28 #include <asm/ip32/mace.h>
ian@0 29 #include <asm/ip32/ip32_ints.h>
ian@0 30
ian@0 31 extern void ip32_be_init(void);
ian@0 32 extern void crime_init(void);
ian@0 33
ian@0 34 #ifdef CONFIG_SGI_O2MACE_ETH
ian@0 35 /*
ian@0 36 * This is taken care of in here 'cause they say using Arc later on is
ian@0 37 * problematic
ian@0 38 */
ian@0 39 extern char o2meth_eaddr[8];
ian@0 40 static inline unsigned char str2hexnum(unsigned char c)
ian@0 41 {
ian@0 42 if (c >= '0' && c <= '9')
ian@0 43 return c - '0';
ian@0 44 if (c >= 'a' && c <= 'f')
ian@0 45 return c - 'a' + 10;
ian@0 46 return 0; /* foo */
ian@0 47 }
ian@0 48
ian@0 49 static inline void str2eaddr(unsigned char *ea, unsigned char *str)
ian@0 50 {
ian@0 51 int i;
ian@0 52
ian@0 53 for (i = 0; i < 6; i++) {
ian@0 54 unsigned char num;
ian@0 55
ian@0 56 if(*str == ':')
ian@0 57 str++;
ian@0 58 num = str2hexnum(*str++) << 4;
ian@0 59 num |= (str2hexnum(*str++));
ian@0 60 ea[i] = num;
ian@0 61 }
ian@0 62 }
ian@0 63 #endif
ian@0 64
ian@0 65 #ifdef CONFIG_SERIAL_8250
ian@0 66 #include <linux/tty.h>
ian@0 67 #include <linux/serial.h>
ian@0 68 #include <linux/serial_core.h>
ian@0 69 #endif /* CONFIG_SERIAL_8250 */
ian@0 70
ian@0 71 /* An arbitrary time; this can be decreased if reliability looks good */
ian@0 72 #define WAIT_MS 10
ian@0 73
ian@0 74 void __init ip32_time_init(void)
ian@0 75 {
ian@0 76 printk(KERN_INFO "Calibrating system timer... ");
ian@0 77 write_c0_count(0);
ian@0 78 crime->timer = 0;
ian@0 79 while (crime->timer < CRIME_MASTER_FREQ * WAIT_MS / 1000) ;
ian@0 80 mips_hpt_frequency = read_c0_count() * 1000 / WAIT_MS;
ian@0 81 printk("%d MHz CPU detected\n", mips_hpt_frequency * 2 / 1000000);
ian@0 82 }
ian@0 83
ian@0 84 void __init plat_timer_setup(struct irqaction *irq)
ian@0 85 {
ian@0 86 irq->handler = no_action;
ian@0 87 setup_irq(IP32_R4K_TIMER_IRQ, irq);
ian@0 88 }
ian@0 89
ian@0 90 void __init plat_mem_setup(void)
ian@0 91 {
ian@0 92 board_be_init = ip32_be_init;
ian@0 93
ian@0 94 rtc_mips_get_time = mc146818_get_cmos_time;
ian@0 95 rtc_mips_set_mmss = mc146818_set_rtc_mmss;
ian@0 96
ian@0 97 board_time_init = ip32_time_init;
ian@0 98
ian@0 99 #ifdef CONFIG_SERIAL_8250
ian@0 100 {
ian@0 101 static struct uart_port o2_serial[2];
ian@0 102
ian@0 103 memset(o2_serial, 0, sizeof(o2_serial));
ian@0 104 o2_serial[0].type = PORT_16550A;
ian@0 105 o2_serial[0].line = 0;
ian@0 106 o2_serial[0].irq = MACEISA_SERIAL1_IRQ;
ian@0 107 o2_serial[0].flags = UPF_SKIP_TEST;
ian@0 108 o2_serial[0].uartclk = 1843200;
ian@0 109 o2_serial[0].iotype = UPIO_MEM;
ian@0 110 o2_serial[0].membase = (char *)&mace->isa.serial1;
ian@0 111 o2_serial[0].fifosize = 14;
ian@0 112 /* How much to shift register offset by. Each UART register
ian@0 113 * is replicated over 256 byte space */
ian@0 114 o2_serial[0].regshift = 8;
ian@0 115 o2_serial[1].type = PORT_16550A;
ian@0 116 o2_serial[1].line = 1;
ian@0 117 o2_serial[1].irq = MACEISA_SERIAL2_IRQ;
ian@0 118 o2_serial[1].flags = UPF_SKIP_TEST;
ian@0 119 o2_serial[1].uartclk = 1843200;
ian@0 120 o2_serial[1].iotype = UPIO_MEM;
ian@0 121 o2_serial[1].membase = (char *)&mace->isa.serial2;
ian@0 122 o2_serial[1].fifosize = 14;
ian@0 123 o2_serial[1].regshift = 8;
ian@0 124
ian@0 125 early_serial_setup(&o2_serial[0]);
ian@0 126 early_serial_setup(&o2_serial[1]);
ian@0 127 }
ian@0 128 #endif
ian@0 129 #ifdef CONFIG_SGI_O2MACE_ETH
ian@0 130 {
ian@0 131 char *mac = ArcGetEnvironmentVariable("eaddr");
ian@0 132 str2eaddr(o2meth_eaddr, mac);
ian@0 133 }
ian@0 134 #endif
ian@0 135
ian@0 136 #if defined(CONFIG_SERIAL_CORE_CONSOLE)
ian@0 137 {
ian@0 138 char* con = ArcGetEnvironmentVariable("console");
ian@0 139 if (con && *con == 'd') {
ian@0 140 static char options[8];
ian@0 141 char *baud = ArcGetEnvironmentVariable("dbaud");
ian@0 142 if (baud)
ian@0 143 strcpy(options, baud);
ian@0 144 add_preferred_console("ttyS", *(con + 1) == '2' ? 1 : 0,
ian@0 145 baud ? options : NULL);
ian@0 146 }
ian@0 147 }
ian@0 148 #endif
ian@0 149 }