ia64/linux-2.6.18-xen.hg

view drivers/mtd/maps/sbc_gxx.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
line source
1 /* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX,
2 SBC-GXm and SBC-GX1 series boards.
4 Copyright (C) 2001 Arcom Control System Ltd
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 $Id: sbc_gxx.c,v 1.35 2005/11/07 11:14:28 gleixner Exp $
22 The SBC-MediaGX / SBC-GXx has up to 16 MiB of
23 Intel StrataFlash (28F320/28F640) in x8 mode.
25 This driver uses the CFI probe and Intel Extended Command Set drivers.
27 The flash is accessed as follows:
29 16 KiB memory window at 0xdc000-0xdffff
31 Two IO address locations for paging
33 0x258
34 bit 0-7: address bit 14-21
35 0x259
36 bit 0-1: address bit 22-23
37 bit 7: 0 - reset/powered down
38 1 - device enabled
40 The single flash device is divided into 3 partition which appear as
41 separate MTD devices.
43 25/04/2001 AJL (Arcom) Modified signon strings and partition sizes
44 (to support bzImages up to 638KiB-ish)
45 */
47 // Includes
49 #include <linux/module.h>
50 #include <linux/slab.h>
51 #include <linux/ioport.h>
52 #include <linux/init.h>
53 #include <asm/io.h>
55 #include <linux/mtd/mtd.h>
56 #include <linux/mtd/map.h>
57 #include <linux/mtd/partitions.h>
59 // Defines
61 // - Hardware specific
63 #define WINDOW_START 0xdc000
65 /* Number of bits in offset. */
66 #define WINDOW_SHIFT 14
67 #define WINDOW_LENGTH (1 << WINDOW_SHIFT)
69 /* The bits for the offset into the window. */
70 #define WINDOW_MASK (WINDOW_LENGTH-1)
71 #define PAGE_IO 0x258
72 #define PAGE_IO_SIZE 2
74 /* bit 7 of 0x259 must be 1 to enable device. */
75 #define DEVICE_ENABLE 0x8000
77 // - Flash / Partition sizing
79 #define MAX_SIZE_KiB 16384
80 #define BOOT_PARTITION_SIZE_KiB 768
81 #define DATA_PARTITION_SIZE_KiB 1280
82 #define APP_PARTITION_SIZE_KiB 6144
84 // Globals
86 static volatile int page_in_window = -1; // Current page in window.
87 static void __iomem *iomapadr;
88 static DEFINE_SPINLOCK(sbc_gxx_spin);
90 /* partition_info gives details on the logical partitions that the split the
91 * single flash device into. If the size if zero we use up to the end of the
92 * device. */
93 static struct mtd_partition partition_info[]={
94 { .name = "SBC-GXx flash boot partition",
95 .offset = 0,
96 .size = BOOT_PARTITION_SIZE_KiB*1024 },
97 { .name = "SBC-GXx flash data partition",
98 .offset = BOOT_PARTITION_SIZE_KiB*1024,
99 .size = (DATA_PARTITION_SIZE_KiB)*1024 },
100 { .name = "SBC-GXx flash application partition",
101 .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
102 };
104 #define NUM_PARTITIONS 3
106 static inline void sbc_gxx_page(struct map_info *map, unsigned long ofs)
107 {
108 unsigned long page = ofs >> WINDOW_SHIFT;
110 if( page!=page_in_window ) {
111 outw( page | DEVICE_ENABLE, PAGE_IO );
112 page_in_window = page;
113 }
114 }
117 static map_word sbc_gxx_read8(struct map_info *map, unsigned long ofs)
118 {
119 map_word ret;
120 spin_lock(&sbc_gxx_spin);
121 sbc_gxx_page(map, ofs);
122 ret.x[0] = readb(iomapadr + (ofs & WINDOW_MASK));
123 spin_unlock(&sbc_gxx_spin);
124 return ret;
125 }
127 static void sbc_gxx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
128 {
129 while(len) {
130 unsigned long thislen = len;
131 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
132 thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
134 spin_lock(&sbc_gxx_spin);
135 sbc_gxx_page(map, from);
136 memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
137 spin_unlock(&sbc_gxx_spin);
138 to += thislen;
139 from += thislen;
140 len -= thislen;
141 }
142 }
144 static void sbc_gxx_write8(struct map_info *map, map_word d, unsigned long adr)
145 {
146 spin_lock(&sbc_gxx_spin);
147 sbc_gxx_page(map, adr);
148 writeb(d.x[0], iomapadr + (adr & WINDOW_MASK));
149 spin_unlock(&sbc_gxx_spin);
150 }
152 static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
153 {
154 while(len) {
155 unsigned long thislen = len;
156 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
157 thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
159 spin_lock(&sbc_gxx_spin);
160 sbc_gxx_page(map, to);
161 memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
162 spin_unlock(&sbc_gxx_spin);
163 to += thislen;
164 from += thislen;
165 len -= thislen;
166 }
167 }
169 static struct map_info sbc_gxx_map = {
170 .name = "SBC-GXx flash",
171 .phys = NO_XIP,
172 .size = MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount
173 of flash so the cfi probe routines find all
174 the chips */
175 .bankwidth = 1,
176 .read = sbc_gxx_read8,
177 .copy_from = sbc_gxx_copy_from,
178 .write = sbc_gxx_write8,
179 .copy_to = sbc_gxx_copy_to
180 };
182 /* MTD device for all of the flash. */
183 static struct mtd_info *all_mtd;
185 static void cleanup_sbc_gxx(void)
186 {
187 if( all_mtd ) {
188 del_mtd_partitions( all_mtd );
189 map_destroy( all_mtd );
190 }
192 iounmap(iomapadr);
193 release_region(PAGE_IO,PAGE_IO_SIZE);
194 }
196 static int __init init_sbc_gxx(void)
197 {
198 iomapadr = ioremap(WINDOW_START, WINDOW_LENGTH);
199 if (!iomapadr) {
200 printk( KERN_ERR"%s: failed to ioremap memory region\n",
201 sbc_gxx_map.name );
202 return -EIO;
203 }
205 if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) {
206 printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
207 sbc_gxx_map.name,
208 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
209 iounmap(iomapadr);
210 return -EAGAIN;
211 }
214 printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
215 sbc_gxx_map.name,
216 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
217 WINDOW_START, WINDOW_START+WINDOW_LENGTH-1 );
219 /* Probe for chip. */
220 all_mtd = do_map_probe( "cfi_probe", &sbc_gxx_map );
221 if( !all_mtd ) {
222 cleanup_sbc_gxx();
223 return -ENXIO;
224 }
226 all_mtd->owner = THIS_MODULE;
228 /* Create MTD devices for each partition. */
229 add_mtd_partitions(all_mtd, partition_info, NUM_PARTITIONS );
231 return 0;
232 }
234 module_init(init_sbc_gxx);
235 module_exit(cleanup_sbc_gxx);
237 MODULE_LICENSE("GPL");
238 MODULE_AUTHOR("Arcom Control Systems Ltd.");
239 MODULE_DESCRIPTION("MTD map driver for SBC-GXm and SBC-GX1 series boards");