ia64/linux-2.6.18-xen.hg

annotate drivers/mtd/maps/scb2_flash.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 * MTD map driver for BIOS Flash on Intel SCB2 boards
ian@0 3 * $Id: scb2_flash.c,v 1.12 2005/03/18 14:04:35 gleixner Exp $
ian@0 4 * Copyright (C) 2002 Sun Microsystems, Inc.
ian@0 5 * Tim Hockin <thockin@sun.com>
ian@0 6 *
ian@0 7 * A few notes on this MTD map:
ian@0 8 *
ian@0 9 * This was developed with a small number of SCB2 boards to test on.
ian@0 10 * Hopefully, Intel has not introducted too many unaccounted variables in the
ian@0 11 * making of this board.
ian@0 12 *
ian@0 13 * The BIOS marks its own memory region as 'reserved' in the e820 map. We
ian@0 14 * try to request it here, but if it fails, we carry on anyway.
ian@0 15 *
ian@0 16 * This is how the chip is attached, so said the schematic:
ian@0 17 * * a 4 MiB (32 Mib) 16 bit chip
ian@0 18 * * a 1 MiB memory region
ian@0 19 * * A20 and A21 pulled up
ian@0 20 * * D8-D15 ignored
ian@0 21 * What this means is that, while we are addressing bytes linearly, we are
ian@0 22 * really addressing words, and discarding the other byte. This means that
ian@0 23 * the chip MUST BE at least 2 MiB. This also means that every block is
ian@0 24 * actually half as big as the chip reports. It also means that accesses of
ian@0 25 * logical address 0 hit higher-address sections of the chip, not physical 0.
ian@0 26 * One can only hope that these 4MiB x16 chips were a lot cheaper than 1MiB x8
ian@0 27 * chips.
ian@0 28 *
ian@0 29 * This driver assumes the chip is not write-protected by an external signal.
ian@0 30 * As of the this writing, that is true, but may change, just to spite me.
ian@0 31 *
ian@0 32 * The actual BIOS layout has been mostly reverse engineered. Intel BIOS
ian@0 33 * updates for this board include 10 related (*.bio - &.bi9) binary files and
ian@0 34 * another separate (*.bbo) binary file. The 10 files are 64k of data + a
ian@0 35 * small header. If the headers are stripped off, the 10 64k files can be
ian@0 36 * concatenated into a 640k image. This is your BIOS image, proper. The
ian@0 37 * separate .bbo file also has a small header. It is the 'Boot Block'
ian@0 38 * recovery BIOS. Once the header is stripped, no further prep is needed.
ian@0 39 * As best I can tell, the BIOS is arranged as such:
ian@0 40 * offset 0x00000 to 0x4ffff (320k): unknown - SCSI BIOS, etc?
ian@0 41 * offset 0x50000 to 0xeffff (640k): BIOS proper
ian@0 42 * offset 0xf0000 ty 0xfffff (64k): Boot Block region
ian@0 43 *
ian@0 44 * Intel's BIOS update program flashes the BIOS and Boot Block in separate
ian@0 45 * steps. Probably a wise thing to do.
ian@0 46 */
ian@0 47
ian@0 48 #include <linux/module.h>
ian@0 49 #include <linux/types.h>
ian@0 50 #include <linux/kernel.h>
ian@0 51 #include <linux/init.h>
ian@0 52 #include <asm/io.h>
ian@0 53 #include <linux/mtd/mtd.h>
ian@0 54 #include <linux/mtd/map.h>
ian@0 55 #include <linux/mtd/cfi.h>
ian@0 56 #include <linux/pci.h>
ian@0 57 #include <linux/pci_ids.h>
ian@0 58
ian@0 59 #define MODNAME "scb2_flash"
ian@0 60 #define SCB2_ADDR 0xfff00000
ian@0 61 #define SCB2_WINDOW 0x00100000
ian@0 62
ian@0 63
ian@0 64 static void __iomem *scb2_ioaddr;
ian@0 65 static struct mtd_info *scb2_mtd;
ian@0 66 static struct map_info scb2_map = {
ian@0 67 .name = "SCB2 BIOS Flash",
ian@0 68 .size = 0,
ian@0 69 .bankwidth = 1,
ian@0 70 };
ian@0 71 static int region_fail;
ian@0 72
ian@0 73 static int __devinit
ian@0 74 scb2_fixup_mtd(struct mtd_info *mtd)
ian@0 75 {
ian@0 76 int i;
ian@0 77 int done = 0;
ian@0 78 struct map_info *map = mtd->priv;
ian@0 79 struct cfi_private *cfi = map->fldrv_priv;
ian@0 80
ian@0 81 /* barf if this doesn't look right */
ian@0 82 if (cfi->cfiq->InterfaceDesc != 1) {
ian@0 83 printk(KERN_ERR MODNAME ": unsupported InterfaceDesc: %#x\n",
ian@0 84 cfi->cfiq->InterfaceDesc);
ian@0 85 return -1;
ian@0 86 }
ian@0 87
ian@0 88 /* I wasn't here. I didn't see. dwmw2. */
ian@0 89
ian@0 90 /* the chip is sometimes bigger than the map - what a waste */
ian@0 91 mtd->size = map->size;
ian@0 92
ian@0 93 /*
ian@0 94 * We only REALLY get half the chip, due to the way it is
ian@0 95 * wired up - D8-D15 are tossed away. We read linear bytes,
ian@0 96 * but in reality we are getting 1/2 of each 16-bit read,
ian@0 97 * which LOOKS linear to us. Because CFI code accounts for
ian@0 98 * things like lock/unlock/erase by eraseregions, we need to
ian@0 99 * fudge them to reflect this. Erases go like this:
ian@0 100 * * send an erase to an address
ian@0 101 * * the chip samples the address and erases the block
ian@0 102 * * add the block erasesize to the address and repeat
ian@0 103 * -- the problem is that addresses are 16-bit addressable
ian@0 104 * -- we end up erasing every-other block
ian@0 105 */
ian@0 106 mtd->erasesize /= 2;
ian@0 107 for (i = 0; i < mtd->numeraseregions; i++) {
ian@0 108 struct mtd_erase_region_info *region = &mtd->eraseregions[i];
ian@0 109 region->erasesize /= 2;
ian@0 110 }
ian@0 111
ian@0 112 /*
ian@0 113 * If the chip is bigger than the map, it is wired with the high
ian@0 114 * address lines pulled up. This makes us access the top portion of
ian@0 115 * the chip, so all our erase-region info is wrong. Start cutting from
ian@0 116 * the bottom.
ian@0 117 */
ian@0 118 for (i = 0; !done && i < mtd->numeraseregions; i++) {
ian@0 119 struct mtd_erase_region_info *region = &mtd->eraseregions[i];
ian@0 120
ian@0 121 if (region->numblocks * region->erasesize > mtd->size) {
ian@0 122 region->numblocks = (mtd->size / region->erasesize);
ian@0 123 done = 1;
ian@0 124 } else {
ian@0 125 region->numblocks = 0;
ian@0 126 }
ian@0 127 region->offset = 0;
ian@0 128 }
ian@0 129
ian@0 130 return 0;
ian@0 131 }
ian@0 132
ian@0 133 /* CSB5's 'Function Control Register' has bits for decoding @ >= 0xffc00000 */
ian@0 134 #define CSB5_FCR 0x41
ian@0 135 #define CSB5_FCR_DECODE_ALL 0x0e
ian@0 136 static int __devinit
ian@0 137 scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent)
ian@0 138 {
ian@0 139 u8 reg;
ian@0 140
ian@0 141 /* enable decoding of the flash region in the south bridge */
ian@0 142 pci_read_config_byte(dev, CSB5_FCR, &reg);
ian@0 143 pci_write_config_byte(dev, CSB5_FCR, reg | CSB5_FCR_DECODE_ALL);
ian@0 144
ian@0 145 if (!request_mem_region(SCB2_ADDR, SCB2_WINDOW, scb2_map.name)) {
ian@0 146 /*
ian@0 147 * The BIOS seems to mark the flash region as 'reserved'
ian@0 148 * in the e820 map. Warn and go about our business.
ian@0 149 */
ian@0 150 printk(KERN_WARNING MODNAME
ian@0 151 ": warning - can't reserve rom window, continuing\n");
ian@0 152 region_fail = 1;
ian@0 153 }
ian@0 154
ian@0 155 /* remap the IO window (w/o caching) */
ian@0 156 scb2_ioaddr = ioremap_nocache(SCB2_ADDR, SCB2_WINDOW);
ian@0 157 if (!scb2_ioaddr) {
ian@0 158 printk(KERN_ERR MODNAME ": Failed to ioremap window!\n");
ian@0 159 if (!region_fail)
ian@0 160 release_mem_region(SCB2_ADDR, SCB2_WINDOW);
ian@0 161 return -ENOMEM;
ian@0 162 }
ian@0 163
ian@0 164 scb2_map.phys = SCB2_ADDR;
ian@0 165 scb2_map.virt = scb2_ioaddr;
ian@0 166 scb2_map.size = SCB2_WINDOW;
ian@0 167
ian@0 168 simple_map_init(&scb2_map);
ian@0 169
ian@0 170 /* try to find a chip */
ian@0 171 scb2_mtd = do_map_probe("cfi_probe", &scb2_map);
ian@0 172
ian@0 173 if (!scb2_mtd) {
ian@0 174 printk(KERN_ERR MODNAME ": flash probe failed!\n");
ian@0 175 iounmap(scb2_ioaddr);
ian@0 176 if (!region_fail)
ian@0 177 release_mem_region(SCB2_ADDR, SCB2_WINDOW);
ian@0 178 return -ENODEV;
ian@0 179 }
ian@0 180
ian@0 181 scb2_mtd->owner = THIS_MODULE;
ian@0 182 if (scb2_fixup_mtd(scb2_mtd) < 0) {
ian@0 183 del_mtd_device(scb2_mtd);
ian@0 184 map_destroy(scb2_mtd);
ian@0 185 iounmap(scb2_ioaddr);
ian@0 186 if (!region_fail)
ian@0 187 release_mem_region(SCB2_ADDR, SCB2_WINDOW);
ian@0 188 return -ENODEV;
ian@0 189 }
ian@0 190
ian@0 191 printk(KERN_NOTICE MODNAME ": chip size 0x%x at offset 0x%x\n",
ian@0 192 scb2_mtd->size, SCB2_WINDOW - scb2_mtd->size);
ian@0 193
ian@0 194 add_mtd_device(scb2_mtd);
ian@0 195
ian@0 196 return 0;
ian@0 197 }
ian@0 198
ian@0 199 static void __devexit
ian@0 200 scb2_flash_remove(struct pci_dev *dev)
ian@0 201 {
ian@0 202 if (!scb2_mtd)
ian@0 203 return;
ian@0 204
ian@0 205 /* disable flash writes */
ian@0 206 if (scb2_mtd->lock)
ian@0 207 scb2_mtd->lock(scb2_mtd, 0, scb2_mtd->size);
ian@0 208
ian@0 209 del_mtd_device(scb2_mtd);
ian@0 210 map_destroy(scb2_mtd);
ian@0 211
ian@0 212 iounmap(scb2_ioaddr);
ian@0 213 scb2_ioaddr = NULL;
ian@0 214
ian@0 215 if (!region_fail)
ian@0 216 release_mem_region(SCB2_ADDR, SCB2_WINDOW);
ian@0 217 pci_set_drvdata(dev, NULL);
ian@0 218 }
ian@0 219
ian@0 220 static struct pci_device_id scb2_flash_pci_ids[] = {
ian@0 221 {
ian@0 222 .vendor = PCI_VENDOR_ID_SERVERWORKS,
ian@0 223 .device = PCI_DEVICE_ID_SERVERWORKS_CSB5,
ian@0 224 .subvendor = PCI_ANY_ID,
ian@0 225 .subdevice = PCI_ANY_ID
ian@0 226 },
ian@0 227 { 0, }
ian@0 228 };
ian@0 229
ian@0 230 static struct pci_driver scb2_flash_driver = {
ian@0 231 .name = "Intel SCB2 BIOS Flash",
ian@0 232 .id_table = scb2_flash_pci_ids,
ian@0 233 .probe = scb2_flash_probe,
ian@0 234 .remove = __devexit_p(scb2_flash_remove),
ian@0 235 };
ian@0 236
ian@0 237 static int __init
ian@0 238 scb2_flash_init(void)
ian@0 239 {
ian@0 240 return pci_register_driver(&scb2_flash_driver);
ian@0 241 }
ian@0 242
ian@0 243 static void __exit
ian@0 244 scb2_flash_exit(void)
ian@0 245 {
ian@0 246 pci_unregister_driver(&scb2_flash_driver);
ian@0 247 }
ian@0 248
ian@0 249 module_init(scb2_flash_init);
ian@0 250 module_exit(scb2_flash_exit);
ian@0 251
ian@0 252 MODULE_LICENSE("GPL");
ian@0 253 MODULE_AUTHOR("Tim Hockin <thockin@sun.com>");
ian@0 254 MODULE_DESCRIPTION("MTD map driver for Intel SCB2 BIOS Flash");
ian@0 255 MODULE_DEVICE_TABLE(pci, scb2_flash_pci_ids);