ia64/linux-2.6.18-xen.hg

annotate arch/mips/sgi-ip27/ip27-xtalk.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) 1999, 2000 Ralf Baechle (ralf@gnu.org)
ian@0 3 * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
ian@0 4 * Copyright (C) 2004 Christoph Hellwig.
ian@0 5 * Released under GPL v2.
ian@0 6 *
ian@0 7 * Generic XTALK initialization code
ian@0 8 */
ian@0 9
ian@0 10 #include <linux/init.h>
ian@0 11 #include <linux/kernel.h>
ian@0 12 #include <asm/sn/types.h>
ian@0 13 #include <asm/sn/klconfig.h>
ian@0 14 #include <asm/sn/hub.h>
ian@0 15 #include <asm/pci/bridge.h>
ian@0 16 #include <asm/xtalk/xtalk.h>
ian@0 17
ian@0 18
ian@0 19 #define XBOW_WIDGET_PART_NUM 0x0
ian@0 20 #define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbow in Xbridge */
ian@0 21 #define BASE_XBOW_PORT 8 /* Lowest external port */
ian@0 22
ian@0 23 extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
ian@0 24
ian@0 25 static int __init probe_one_port(nasid_t nasid, int widget, int masterwid)
ian@0 26 {
ian@0 27 widgetreg_t widget_id;
ian@0 28 xwidget_part_num_t partnum;
ian@0 29
ian@0 30 widget_id = *(volatile widgetreg_t *)
ian@0 31 (RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID);
ian@0 32 partnum = XWIDGET_PART_NUM(widget_id);
ian@0 33
ian@0 34 printk(KERN_INFO "Cpu %d, Nasid 0x%x, widget 0x%x (partnum 0x%x) is ",
ian@0 35 smp_processor_id(), nasid, widget, partnum);
ian@0 36
ian@0 37 switch (partnum) {
ian@0 38 case BRIDGE_WIDGET_PART_NUM:
ian@0 39 case XBRIDGE_WIDGET_PART_NUM:
ian@0 40 bridge_probe(nasid, widget, masterwid);
ian@0 41 break;
ian@0 42 default:
ian@0 43 break;
ian@0 44 }
ian@0 45
ian@0 46 return 0;
ian@0 47 }
ian@0 48
ian@0 49 static int __init xbow_probe(nasid_t nasid)
ian@0 50 {
ian@0 51 lboard_t *brd;
ian@0 52 klxbow_t *xbow_p;
ian@0 53 unsigned masterwid, i;
ian@0 54
ian@0 55 printk("is xbow\n");
ian@0 56
ian@0 57 /*
ian@0 58 * found xbow, so may have multiple bridges
ian@0 59 * need to probe xbow
ian@0 60 */
ian@0 61 brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8);
ian@0 62 if (!brd)
ian@0 63 return -ENODEV;
ian@0 64
ian@0 65 xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW);
ian@0 66 if (!xbow_p)
ian@0 67 return -ENODEV;
ian@0 68
ian@0 69 /*
ian@0 70 * Okay, here's a xbow. Lets arbitrate and find
ian@0 71 * out if we should initialize it. Set enabled
ian@0 72 * hub connected at highest or lowest widget as
ian@0 73 * master.
ian@0 74 */
ian@0 75 #ifdef WIDGET_A
ian@0 76 i = HUB_WIDGET_ID_MAX + 1;
ian@0 77 do {
ian@0 78 i--;
ian@0 79 } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
ian@0 80 (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
ian@0 81 #else
ian@0 82 i = HUB_WIDGET_ID_MIN - 1;
ian@0 83 do {
ian@0 84 i++;
ian@0 85 } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
ian@0 86 (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
ian@0 87 #endif
ian@0 88
ian@0 89 masterwid = i;
ian@0 90 if (nasid != XBOW_PORT_NASID(xbow_p, i))
ian@0 91 return 1;
ian@0 92
ian@0 93 for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++) {
ian@0 94 if (XBOW_PORT_IS_ENABLED(xbow_p, i) &&
ian@0 95 XBOW_PORT_TYPE_IO(xbow_p, i))
ian@0 96 probe_one_port(nasid, i, masterwid);
ian@0 97 }
ian@0 98
ian@0 99 return 0;
ian@0 100 }
ian@0 101
ian@0 102 void __init xtalk_probe_node(cnodeid_t nid)
ian@0 103 {
ian@0 104 volatile u64 hubreg;
ian@0 105 nasid_t nasid;
ian@0 106 xwidget_part_num_t partnum;
ian@0 107 widgetreg_t widget_id;
ian@0 108
ian@0 109 nasid = COMPACT_TO_NASID_NODEID(nid);
ian@0 110 hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
ian@0 111
ian@0 112 /* check whether the link is up */
ian@0 113 if (!(hubreg & IIO_LLP_CSR_IS_UP))
ian@0 114 return;
ian@0 115
ian@0 116 widget_id = *(volatile widgetreg_t *)
ian@0 117 (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
ian@0 118 partnum = XWIDGET_PART_NUM(widget_id);
ian@0 119
ian@0 120 printk(KERN_INFO "Cpu %d, Nasid 0x%x: partnum 0x%x is ",
ian@0 121 smp_processor_id(), nasid, partnum);
ian@0 122
ian@0 123 switch (partnum) {
ian@0 124 case BRIDGE_WIDGET_PART_NUM:
ian@0 125 bridge_probe(nasid, 0x8, 0xa);
ian@0 126 break;
ian@0 127 case XBOW_WIDGET_PART_NUM:
ian@0 128 case XXBOW_WIDGET_PART_NUM:
ian@0 129 xbow_probe(nasid);
ian@0 130 break;
ian@0 131 default:
ian@0 132 printk(" unknown widget??\n");
ian@0 133 break;
ian@0 134 }
ian@0 135 }