ia64/linux-2.6.18-xen.hg

annotate drivers/zorro/zorro.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 * $Id: zorro.c,v 1.1.2.1 1998/06/07 23:21:02 geert Exp $
ian@0 3 *
ian@0 4 * Zorro Bus Services
ian@0 5 *
ian@0 6 * Copyright (C) 1995-2003 Geert Uytterhoeven
ian@0 7 *
ian@0 8 * This file is subject to the terms and conditions of the GNU General Public
ian@0 9 * License. See the file COPYING in the main directory of this archive
ian@0 10 * for more details.
ian@0 11 */
ian@0 12
ian@0 13 #include <linux/module.h>
ian@0 14 #include <linux/types.h>
ian@0 15 #include <linux/kernel.h>
ian@0 16 #include <linux/init.h>
ian@0 17 #include <linux/zorro.h>
ian@0 18 #include <linux/bitops.h>
ian@0 19 #include <linux/string.h>
ian@0 20
ian@0 21 #include <asm/setup.h>
ian@0 22 #include <asm/amigahw.h>
ian@0 23
ian@0 24 #include "zorro.h"
ian@0 25
ian@0 26
ian@0 27 /*
ian@0 28 * Zorro Expansion Devices
ian@0 29 */
ian@0 30
ian@0 31 u_int zorro_num_autocon = 0;
ian@0 32 struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
ian@0 33
ian@0 34
ian@0 35 /*
ian@0 36 * Single Zorro bus
ian@0 37 */
ian@0 38
ian@0 39 struct zorro_bus zorro_bus = {\
ian@0 40 .resources = {
ian@0 41 /* Zorro II regions (on Zorro II/III) */
ian@0 42 { .name = "Zorro II exp", .start = 0x00e80000, .end = 0x00efffff },
ian@0 43 { .name = "Zorro II mem", .start = 0x00200000, .end = 0x009fffff },
ian@0 44 /* Zorro III regions (on Zorro III only) */
ian@0 45 { .name = "Zorro III exp", .start = 0xff000000, .end = 0xffffffff },
ian@0 46 { .name = "Zorro III cfg", .start = 0x40000000, .end = 0x7fffffff }
ian@0 47 },
ian@0 48 .name = "Zorro bus"
ian@0 49 };
ian@0 50
ian@0 51
ian@0 52 /*
ian@0 53 * Find Zorro Devices
ian@0 54 */
ian@0 55
ian@0 56 struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from)
ian@0 57 {
ian@0 58 struct zorro_dev *z;
ian@0 59
ian@0 60 if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
ian@0 61 return NULL;
ian@0 62
ian@0 63 for (z = from ? from+1 : &zorro_autocon[0];
ian@0 64 z < zorro_autocon+zorro_num_autocon;
ian@0 65 z++)
ian@0 66 if (id == ZORRO_WILDCARD || id == z->id)
ian@0 67 return z;
ian@0 68 return NULL;
ian@0 69 }
ian@0 70
ian@0 71
ian@0 72 /*
ian@0 73 * Bitmask indicating portions of available Zorro II RAM that are unused
ian@0 74 * by the system. Every bit represents a 64K chunk, for a maximum of 8MB
ian@0 75 * (128 chunks, physical 0x00200000-0x009fffff).
ian@0 76 *
ian@0 77 * If you want to use (= allocate) portions of this RAM, you should clear
ian@0 78 * the corresponding bits.
ian@0 79 *
ian@0 80 * Possible uses:
ian@0 81 * - z2ram device
ian@0 82 * - SCSI DMA bounce buffers
ian@0 83 *
ian@0 84 * FIXME: use the normal resource management
ian@0 85 */
ian@0 86
ian@0 87 DECLARE_BITMAP(zorro_unused_z2ram, 128);
ian@0 88
ian@0 89
ian@0 90 static void __init mark_region(unsigned long start, unsigned long end,
ian@0 91 int flag)
ian@0 92 {
ian@0 93 if (flag)
ian@0 94 start += Z2RAM_CHUNKMASK;
ian@0 95 else
ian@0 96 end += Z2RAM_CHUNKMASK;
ian@0 97 start &= ~Z2RAM_CHUNKMASK;
ian@0 98 end &= ~Z2RAM_CHUNKMASK;
ian@0 99
ian@0 100 if (end <= Z2RAM_START || start >= Z2RAM_END)
ian@0 101 return;
ian@0 102 start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START;
ian@0 103 end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START;
ian@0 104 while (start < end) {
ian@0 105 u32 chunk = start>>Z2RAM_CHUNKSHIFT;
ian@0 106 if (flag)
ian@0 107 set_bit(chunk, zorro_unused_z2ram);
ian@0 108 else
ian@0 109 clear_bit(chunk, zorro_unused_z2ram);
ian@0 110 start += Z2RAM_CHUNKSIZE;
ian@0 111 }
ian@0 112 }
ian@0 113
ian@0 114
ian@0 115 static struct resource __init *zorro_find_parent_resource(struct zorro_dev *z)
ian@0 116 {
ian@0 117 int i;
ian@0 118
ian@0 119 for (i = 0; i < zorro_bus.num_resources; i++)
ian@0 120 if (zorro_resource_start(z) >= zorro_bus.resources[i].start &&
ian@0 121 zorro_resource_end(z) <= zorro_bus.resources[i].end)
ian@0 122 return &zorro_bus.resources[i];
ian@0 123 return &iomem_resource;
ian@0 124 }
ian@0 125
ian@0 126
ian@0 127 /*
ian@0 128 * Initialization
ian@0 129 */
ian@0 130
ian@0 131 static int __init zorro_init(void)
ian@0 132 {
ian@0 133 struct zorro_dev *z;
ian@0 134 unsigned int i;
ian@0 135
ian@0 136 if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
ian@0 137 return 0;
ian@0 138
ian@0 139 pr_info("Zorro: Probing AutoConfig expansion devices: %d device%s\n",
ian@0 140 zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
ian@0 141
ian@0 142 /* Initialize the Zorro bus */
ian@0 143 INIT_LIST_HEAD(&zorro_bus.devices);
ian@0 144 strcpy(zorro_bus.dev.bus_id, "zorro");
ian@0 145 device_register(&zorro_bus.dev);
ian@0 146
ian@0 147 /* Request the resources */
ian@0 148 zorro_bus.num_resources = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
ian@0 149 for (i = 0; i < zorro_bus.num_resources; i++)
ian@0 150 request_resource(&iomem_resource, &zorro_bus.resources[i]);
ian@0 151
ian@0 152 /* Register all devices */
ian@0 153 for (i = 0; i < zorro_num_autocon; i++) {
ian@0 154 z = &zorro_autocon[i];
ian@0 155 z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
ian@0 156 if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
ian@0 157 /* GVP quirk */
ian@0 158 unsigned long magic = zorro_resource_start(z)+0x8000;
ian@0 159 z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
ian@0 160 }
ian@0 161 sprintf(z->name, "Zorro device %08x", z->id);
ian@0 162 zorro_name_device(z);
ian@0 163 z->resource.name = z->name;
ian@0 164 if (request_resource(zorro_find_parent_resource(z), &z->resource))
ian@0 165 printk(KERN_ERR "Zorro: Address space collision on device %s "
ian@0 166 "[%lx:%lx]\n",
ian@0 167 z->name, zorro_resource_start(z), zorro_resource_end(z));
ian@0 168 sprintf(z->dev.bus_id, "%02x", i);
ian@0 169 z->dev.parent = &zorro_bus.dev;
ian@0 170 z->dev.bus = &zorro_bus_type;
ian@0 171 device_register(&z->dev);
ian@0 172 zorro_create_sysfs_dev_files(z);
ian@0 173 }
ian@0 174
ian@0 175 /* Mark all available Zorro II memory */
ian@0 176 zorro_for_each_dev(z) {
ian@0 177 if (z->rom.er_Type & ERTF_MEMLIST)
ian@0 178 mark_region(zorro_resource_start(z), zorro_resource_end(z)+1, 1);
ian@0 179 }
ian@0 180
ian@0 181 /* Unmark all used Zorro II memory */
ian@0 182 for (i = 0; i < m68k_num_memory; i++)
ian@0 183 if (m68k_memory[i].addr < 16*1024*1024)
ian@0 184 mark_region(m68k_memory[i].addr,
ian@0 185 m68k_memory[i].addr+m68k_memory[i].size, 0);
ian@0 186
ian@0 187 return 0;
ian@0 188 }
ian@0 189
ian@0 190 subsys_initcall(zorro_init);
ian@0 191
ian@0 192 EXPORT_SYMBOL(zorro_find_device);
ian@0 193 EXPORT_SYMBOL(zorro_unused_z2ram);
ian@0 194
ian@0 195 MODULE_LICENSE("GPL");