ia64/linux-2.6.18-xen.hg

annotate arch/sparc/prom/misc.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 /* $Id: misc.c,v 1.18 2000/08/26 02:38:03 anton Exp $
ian@0 2 * misc.c: Miscellaneous prom functions that don't belong
ian@0 3 * anywhere else.
ian@0 4 *
ian@0 5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
ian@0 6 */
ian@0 7
ian@0 8 #include <linux/types.h>
ian@0 9 #include <linux/kernel.h>
ian@0 10 #include <linux/sched.h>
ian@0 11 #include <asm/openprom.h>
ian@0 12 #include <asm/oplib.h>
ian@0 13 #include <asm/auxio.h>
ian@0 14 #include <asm/system.h>
ian@0 15
ian@0 16 extern void restore_current(void);
ian@0 17
ian@0 18 DEFINE_SPINLOCK(prom_lock);
ian@0 19
ian@0 20 /* Reset and reboot the machine with the command 'bcommand'. */
ian@0 21 void
ian@0 22 prom_reboot(char *bcommand)
ian@0 23 {
ian@0 24 unsigned long flags;
ian@0 25 spin_lock_irqsave(&prom_lock, flags);
ian@0 26 (*(romvec->pv_reboot))(bcommand);
ian@0 27 /* Never get here. */
ian@0 28 restore_current();
ian@0 29 spin_unlock_irqrestore(&prom_lock, flags);
ian@0 30 }
ian@0 31
ian@0 32 /* Forth evaluate the expression contained in 'fstring'. */
ian@0 33 void
ian@0 34 prom_feval(char *fstring)
ian@0 35 {
ian@0 36 unsigned long flags;
ian@0 37 if(!fstring || fstring[0] == 0)
ian@0 38 return;
ian@0 39 spin_lock_irqsave(&prom_lock, flags);
ian@0 40 if(prom_vers == PROM_V0)
ian@0 41 (*(romvec->pv_fortheval.v0_eval))(strlen(fstring), fstring);
ian@0 42 else
ian@0 43 (*(romvec->pv_fortheval.v2_eval))(fstring);
ian@0 44 restore_current();
ian@0 45 spin_unlock_irqrestore(&prom_lock, flags);
ian@0 46 }
ian@0 47
ian@0 48 /* We want to do this more nicely some day. */
ian@0 49 extern void (*prom_palette)(int);
ian@0 50
ian@0 51 /* Drop into the prom, with the chance to continue with the 'go'
ian@0 52 * prom command.
ian@0 53 */
ian@0 54 void
ian@0 55 prom_cmdline(void)
ian@0 56 {
ian@0 57 extern void install_obp_ticker(void);
ian@0 58 extern void install_linux_ticker(void);
ian@0 59 unsigned long flags;
ian@0 60
ian@0 61 if(!serial_console && prom_palette)
ian@0 62 prom_palette (1);
ian@0 63 spin_lock_irqsave(&prom_lock, flags);
ian@0 64 install_obp_ticker();
ian@0 65 (*(romvec->pv_abort))();
ian@0 66 restore_current();
ian@0 67 install_linux_ticker();
ian@0 68 spin_unlock_irqrestore(&prom_lock, flags);
ian@0 69 #ifdef CONFIG_SUN_AUXIO
ian@0 70 set_auxio(AUXIO_LED, 0);
ian@0 71 #endif
ian@0 72 if(!serial_console && prom_palette)
ian@0 73 prom_palette (0);
ian@0 74 }
ian@0 75
ian@0 76 /* Drop into the prom, but completely terminate the program.
ian@0 77 * No chance of continuing.
ian@0 78 */
ian@0 79 void
ian@0 80 prom_halt(void)
ian@0 81 {
ian@0 82 unsigned long flags;
ian@0 83 again:
ian@0 84 spin_lock_irqsave(&prom_lock, flags);
ian@0 85 (*(romvec->pv_halt))();
ian@0 86 /* Never get here. */
ian@0 87 restore_current();
ian@0 88 spin_unlock_irqrestore(&prom_lock, flags);
ian@0 89 goto again; /* PROM is out to get me -DaveM */
ian@0 90 }
ian@0 91
ian@0 92 typedef void (*sfunc_t)(void);
ian@0 93
ian@0 94 /* Set prom sync handler to call function 'funcp'. */
ian@0 95 void
ian@0 96 prom_setsync(sfunc_t funcp)
ian@0 97 {
ian@0 98 if(!funcp) return;
ian@0 99 *romvec->pv_synchook = funcp;
ian@0 100 }
ian@0 101
ian@0 102 /* Get the idprom and stuff it into buffer 'idbuf'. Returns the
ian@0 103 * format type. 'num_bytes' is the number of bytes that your idbuf
ian@0 104 * has space for. Returns 0xff on error.
ian@0 105 */
ian@0 106 unsigned char
ian@0 107 prom_get_idprom(char *idbuf, int num_bytes)
ian@0 108 {
ian@0 109 int len;
ian@0 110
ian@0 111 len = prom_getproplen(prom_root_node, "idprom");
ian@0 112 if((len>num_bytes) || (len==-1)) return 0xff;
ian@0 113 if(!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
ian@0 114 return idbuf[0];
ian@0 115
ian@0 116 return 0xff;
ian@0 117 }
ian@0 118
ian@0 119 /* Get the major prom version number. */
ian@0 120 int
ian@0 121 prom_version(void)
ian@0 122 {
ian@0 123 return romvec->pv_romvers;
ian@0 124 }
ian@0 125
ian@0 126 /* Get the prom plugin-revision. */
ian@0 127 int
ian@0 128 prom_getrev(void)
ian@0 129 {
ian@0 130 return prom_rev;
ian@0 131 }
ian@0 132
ian@0 133 /* Get the prom firmware print revision. */
ian@0 134 int
ian@0 135 prom_getprev(void)
ian@0 136 {
ian@0 137 return prom_prev;
ian@0 138 }