ia64/linux-2.6.18-xen.hg

annotate arch/sparc/prom/sun4prom.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 * Copyright (C) 1996 The Australian National University.
ian@0 3 * Copyright (C) 1996 Fujitsu Laboratories Limited
ian@0 4 * Copyright (C) 1997 Michael A. Griffith (grif@acm.org)
ian@0 5 * Copyright (C) 1997 Sun Weenie (ko@ko.reno.nv.us)
ian@0 6 * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
ian@0 7 *
ian@0 8 * This software may be distributed under the terms of the Gnu
ian@0 9 * Public License version 2 or later
ian@0 10 *
ian@0 11 * fake a really simple Sun prom for the SUN4
ian@0 12 */
ian@0 13
ian@0 14 #include <linux/kernel.h>
ian@0 15 #include <linux/string.h>
ian@0 16 #include <asm/oplib.h>
ian@0 17 #include <asm/idprom.h>
ian@0 18 #include <asm/machines.h>
ian@0 19 #include <asm/sun4prom.h>
ian@0 20 #include <asm/asi.h>
ian@0 21 #include <asm/contregs.h>
ian@0 22 #include <linux/init.h>
ian@0 23
ian@0 24 static struct linux_romvec sun4romvec;
ian@0 25 static struct idprom sun4_idprom;
ian@0 26
ian@0 27 struct property {
ian@0 28 char *name;
ian@0 29 char *value;
ian@0 30 int length;
ian@0 31 };
ian@0 32
ian@0 33 struct node {
ian@0 34 int level;
ian@0 35 struct property *properties;
ian@0 36 };
ian@0 37
ian@0 38 struct property null_properties = { NULL, NULL, -1 };
ian@0 39
ian@0 40 struct property root_properties[] = {
ian@0 41 {"device_type", "cpu", 4},
ian@0 42 {"idprom", (char *)&sun4_idprom, sizeof(struct idprom)},
ian@0 43 {NULL, NULL, -1}
ian@0 44 };
ian@0 45
ian@0 46 struct node nodes[] = {
ian@0 47 { 0, &null_properties },
ian@0 48 { 0, root_properties },
ian@0 49 { -1,&null_properties }
ian@0 50 };
ian@0 51
ian@0 52
ian@0 53 static int no_nextnode(int node)
ian@0 54 {
ian@0 55 if (nodes[node].level == nodes[node+1].level)
ian@0 56 return node+1;
ian@0 57 return -1;
ian@0 58 }
ian@0 59
ian@0 60 static int no_child(int node)
ian@0 61 {
ian@0 62 if (nodes[node].level == nodes[node+1].level-1)
ian@0 63 return node+1;
ian@0 64 return -1;
ian@0 65 }
ian@0 66
ian@0 67 static struct property *find_property(int node,char *name)
ian@0 68 {
ian@0 69 struct property *prop = &nodes[node].properties[0];
ian@0 70 while (prop && prop->name) {
ian@0 71 if (strcmp(prop->name,name) == 0) return prop;
ian@0 72 prop++;
ian@0 73 }
ian@0 74 return NULL;
ian@0 75 }
ian@0 76
ian@0 77 static int no_proplen(int node,char *name)
ian@0 78 {
ian@0 79 struct property *prop = find_property(node,name);
ian@0 80 if (prop) return prop->length;
ian@0 81 return -1;
ian@0 82 }
ian@0 83
ian@0 84 static int no_getprop(int node,char *name,char *value)
ian@0 85 {
ian@0 86 struct property *prop = find_property(node,name);
ian@0 87 if (prop) {
ian@0 88 memcpy(value,prop->value,prop->length);
ian@0 89 return 1;
ian@0 90 }
ian@0 91 return -1;
ian@0 92 }
ian@0 93
ian@0 94 static int no_setprop(int node,char *name,char *value,int len)
ian@0 95 {
ian@0 96 return -1;
ian@0 97 }
ian@0 98
ian@0 99 static char *no_nextprop(int node,char *name)
ian@0 100 {
ian@0 101 struct property *prop = find_property(node,name);
ian@0 102 if (prop) return prop[1].name;
ian@0 103 return NULL;
ian@0 104 }
ian@0 105
ian@0 106 static struct linux_nodeops sun4_nodeops = {
ian@0 107 no_nextnode,
ian@0 108 no_child,
ian@0 109 no_proplen,
ian@0 110 no_getprop,
ian@0 111 no_setprop,
ian@0 112 no_nextprop
ian@0 113 };
ian@0 114
ian@0 115 static int synch_hook;
ian@0 116
ian@0 117 struct linux_romvec * __init sun4_prom_init(void)
ian@0 118 {
ian@0 119 int i;
ian@0 120 unsigned char x;
ian@0 121 char *p;
ian@0 122
ian@0 123 p = (char *)&sun4_idprom;
ian@0 124 for (i = 0; i < sizeof(sun4_idprom); i++) {
ian@0 125 __asm__ __volatile__ ("lduba [%1] %2, %0" : "=r" (x) :
ian@0 126 "r" (AC_IDPROM + i), "i" (ASI_CONTROL));
ian@0 127 *p++ = x;
ian@0 128 }
ian@0 129
ian@0 130 memset(&sun4romvec,0,sizeof(sun4romvec));
ian@0 131
ian@0 132 sun4_romvec = (linux_sun4_romvec *) SUN4_PROM_VECTOR;
ian@0 133
ian@0 134 sun4romvec.pv_romvers = 40;
ian@0 135 sun4romvec.pv_nodeops = &sun4_nodeops;
ian@0 136 sun4romvec.pv_reboot = sun4_romvec->reboot;
ian@0 137 sun4romvec.pv_abort = sun4_romvec->abortentry;
ian@0 138 sun4romvec.pv_halt = sun4_romvec->exittomon;
ian@0 139 sun4romvec.pv_synchook = (void (**)(void))&synch_hook;
ian@0 140 sun4romvec.pv_setctxt = sun4_romvec->setcxsegmap;
ian@0 141 sun4romvec.pv_v0bootargs = sun4_romvec->bootParam;
ian@0 142 sun4romvec.pv_nbgetchar = sun4_romvec->mayget;
ian@0 143 sun4romvec.pv_nbputchar = sun4_romvec->mayput;
ian@0 144 sun4romvec.pv_stdin = sun4_romvec->insource;
ian@0 145 sun4romvec.pv_stdout = sun4_romvec->outsink;
ian@0 146
ian@0 147 /*
ian@0 148 * We turn on the LEDs to let folks without monitors or
ian@0 149 * terminals know we booted. Nothing too fancy now. They
ian@0 150 * are all on, except for LED 5, which blinks. When we
ian@0 151 * have more time, we can teach the penguin to say "By your
ian@0 152 * command" or "Activating turbo boost, Michael". :-)
ian@0 153 */
ian@0 154 sun4_romvec->setLEDs(NULL);
ian@0 155
ian@0 156 printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n",
ian@0 157 sun4_romvec->monid,
ian@0 158 sun4_romvec->romvecversion);
ian@0 159
ian@0 160 return &sun4romvec;
ian@0 161 }