ia64/linux-2.6.18-xen.hg

view drivers/block/smart1,2.h @ 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 /*
2 * Disk Array driver for Compaq SMART2 Controllers
3 * Copyright 1998 Compaq Computer Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13 * NON INFRINGEMENT. See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 * Questions/Comments/Bugfixes to iss_storagedev@hp.com
20 *
21 * If you want to make changes, improve or add functionality to this
22 * driver, you'll probably need the Compaq Array Controller Interface
23 * Specificiation (Document number ECG086/1198)
24 */
26 /*
27 * This file contains the controller communication implementation for
28 * Compaq SMART-1 and SMART-2 controllers. To the best of my knowledge,
29 * this should support:
30 *
31 * PCI:
32 * SMART-2/P, SMART-2DH, SMART-2SL, SMART-221, SMART-3100ES, SMART-3200
33 * Integerated SMART Array Controller, SMART-4200, SMART-4250ES
34 *
35 * EISA:
36 * SMART-2/E, SMART, IAES, IDA-2, IDA
37 */
39 /*
40 * Memory mapped FIFO interface (SMART 42xx cards)
41 */
42 static void smart4_submit_command(ctlr_info_t *h, cmdlist_t *c)
43 {
44 writel(c->busaddr, h->vaddr + S42XX_REQUEST_PORT_OFFSET);
45 }
47 /*
48 * This card is the opposite of the other cards.
49 * 0 turns interrupts on...
50 * 0x08 turns them off...
51 */
52 static void smart4_intr_mask(ctlr_info_t *h, unsigned long val)
53 {
54 if (val)
55 { /* Turn interrupts on */
56 writel(0, h->vaddr + S42XX_REPLY_INTR_MASK_OFFSET);
57 } else /* Turn them off */
58 {
59 writel( S42XX_INTR_OFF,
60 h->vaddr + S42XX_REPLY_INTR_MASK_OFFSET);
61 }
62 }
64 /*
65 * For older cards FIFO Full = 0.
66 * On this card 0 means there is room, anything else FIFO Full.
67 *
68 */
69 static unsigned long smart4_fifo_full(ctlr_info_t *h)
70 {
72 return (!readl(h->vaddr + S42XX_REQUEST_PORT_OFFSET));
73 }
75 /* This type of controller returns -1 if the fifo is empty,
76 * Not 0 like the others.
77 * And we need to let it know we read a value out
78 */
79 static unsigned long smart4_completed(ctlr_info_t *h)
80 {
81 long register_value
82 = readl(h->vaddr + S42XX_REPLY_PORT_OFFSET);
84 /* Fifo is empty */
85 if( register_value == 0xffffffff)
86 return 0;
88 /* Need to let it know we got the reply */
89 /* We do this by writing a 0 to the port we just read from */
90 writel(0, h->vaddr + S42XX_REPLY_PORT_OFFSET);
92 return ((unsigned long) register_value);
93 }
95 /*
96 * This hardware returns interrupt pending at a different place and
97 * it does not tell us if the fifo is empty, we will have check
98 * that by getting a 0 back from the comamnd_completed call.
99 */
100 static unsigned long smart4_intr_pending(ctlr_info_t *h)
101 {
102 unsigned long register_value =
103 readl(h->vaddr + S42XX_INTR_STATUS);
105 if( register_value & S42XX_INTR_PENDING)
106 return FIFO_NOT_EMPTY;
107 return 0 ;
108 }
110 static struct access_method smart4_access = {
111 smart4_submit_command,
112 smart4_intr_mask,
113 smart4_fifo_full,
114 smart4_intr_pending,
115 smart4_completed,
116 };
118 /*
119 * Memory mapped FIFO interface (PCI SMART2 and SMART 3xxx cards)
120 */
121 static void smart2_submit_command(ctlr_info_t *h, cmdlist_t *c)
122 {
123 writel(c->busaddr, h->vaddr + COMMAND_FIFO);
124 }
126 static void smart2_intr_mask(ctlr_info_t *h, unsigned long val)
127 {
128 writel(val, h->vaddr + INTR_MASK);
129 }
131 static unsigned long smart2_fifo_full(ctlr_info_t *h)
132 {
133 return readl(h->vaddr + COMMAND_FIFO);
134 }
136 static unsigned long smart2_completed(ctlr_info_t *h)
137 {
138 return readl(h->vaddr + COMMAND_COMPLETE_FIFO);
139 }
141 static unsigned long smart2_intr_pending(ctlr_info_t *h)
142 {
143 return readl(h->vaddr + INTR_PENDING);
144 }
146 static struct access_method smart2_access = {
147 smart2_submit_command,
148 smart2_intr_mask,
149 smart2_fifo_full,
150 smart2_intr_pending,
151 smart2_completed,
152 };
154 /*
155 * IO access for SMART-2/E cards
156 */
157 static void smart2e_submit_command(ctlr_info_t *h, cmdlist_t *c)
158 {
159 outl(c->busaddr, h->io_mem_addr + COMMAND_FIFO);
160 }
162 static void smart2e_intr_mask(ctlr_info_t *h, unsigned long val)
163 {
164 outl(val, h->io_mem_addr + INTR_MASK);
165 }
167 static unsigned long smart2e_fifo_full(ctlr_info_t *h)
168 {
169 return inl(h->io_mem_addr + COMMAND_FIFO);
170 }
172 static unsigned long smart2e_completed(ctlr_info_t *h)
173 {
174 return inl(h->io_mem_addr + COMMAND_COMPLETE_FIFO);
175 }
177 static unsigned long smart2e_intr_pending(ctlr_info_t *h)
178 {
179 return inl(h->io_mem_addr + INTR_PENDING);
180 }
182 static struct access_method smart2e_access = {
183 smart2e_submit_command,
184 smart2e_intr_mask,
185 smart2e_fifo_full,
186 smart2e_intr_pending,
187 smart2e_completed,
188 };
190 /*
191 * IO access for older SMART-1 type cards
192 */
193 #define SMART1_SYSTEM_MASK 0xC8E
194 #define SMART1_SYSTEM_DOORBELL 0xC8F
195 #define SMART1_LOCAL_MASK 0xC8C
196 #define SMART1_LOCAL_DOORBELL 0xC8D
197 #define SMART1_INTR_MASK 0xC89
198 #define SMART1_LISTADDR 0xC90
199 #define SMART1_LISTLEN 0xC94
200 #define SMART1_TAG 0xC97
201 #define SMART1_COMPLETE_ADDR 0xC98
202 #define SMART1_LISTSTATUS 0xC9E
204 #define CHANNEL_BUSY 0x01
205 #define CHANNEL_CLEAR 0x02
207 static void smart1_submit_command(ctlr_info_t *h, cmdlist_t *c)
208 {
209 /*
210 * This __u16 is actually a bunch of control flags on SMART
211 * and below. We want them all to be zero.
212 */
213 c->hdr.size = 0;
215 outb(CHANNEL_CLEAR, h->io_mem_addr + SMART1_SYSTEM_DOORBELL);
217 outl(c->busaddr, h->io_mem_addr + SMART1_LISTADDR);
218 outw(c->size, h->io_mem_addr + SMART1_LISTLEN);
220 outb(CHANNEL_BUSY, h->io_mem_addr + SMART1_LOCAL_DOORBELL);
221 }
223 static void smart1_intr_mask(ctlr_info_t *h, unsigned long val)
224 {
225 if (val == 1) {
226 outb(0xFD, h->io_mem_addr + SMART1_SYSTEM_DOORBELL);
227 outb(CHANNEL_BUSY, h->io_mem_addr + SMART1_LOCAL_DOORBELL);
228 outb(0x01, h->io_mem_addr + SMART1_INTR_MASK);
229 outb(0x01, h->io_mem_addr + SMART1_SYSTEM_MASK);
230 } else {
231 outb(0, h->io_mem_addr + 0xC8E);
232 }
233 }
235 static unsigned long smart1_fifo_full(ctlr_info_t *h)
236 {
237 unsigned char chan;
238 chan = inb(h->io_mem_addr + SMART1_SYSTEM_DOORBELL) & CHANNEL_CLEAR;
239 return chan;
240 }
242 static unsigned long smart1_completed(ctlr_info_t *h)
243 {
244 unsigned char status;
245 unsigned long cmd;
247 if (inb(h->io_mem_addr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY) {
248 outb(CHANNEL_BUSY, h->io_mem_addr + SMART1_SYSTEM_DOORBELL);
250 cmd = inl(h->io_mem_addr + SMART1_COMPLETE_ADDR);
251 status = inb(h->io_mem_addr + SMART1_LISTSTATUS);
253 outb(CHANNEL_CLEAR, h->io_mem_addr + SMART1_LOCAL_DOORBELL);
255 /*
256 * this is x86 (actually compaq x86) only, so it's ok
257 */
258 if (cmd) ((cmdlist_t*)bus_to_virt(cmd))->req.hdr.rcode = status;
259 } else {
260 cmd = 0;
261 }
262 return cmd;
263 }
265 static unsigned long smart1_intr_pending(ctlr_info_t *h)
266 {
267 unsigned char chan;
268 chan = inb(h->io_mem_addr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY;
269 return chan;
270 }
272 static struct access_method smart1_access = {
273 smart1_submit_command,
274 smart1_intr_mask,
275 smart1_fifo_full,
276 smart1_intr_pending,
277 smart1_completed,
278 };