ia64/linux-2.6.18-xen.hg

view drivers/mca/mca-device.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 /* -*- mode: c; c-basic-offset: 8 -*- */
3 /*
4 * MCA device support functions
5 *
6 * These functions support the ongoing device access API.
7 *
8 * (C) 2002 James Bottomley <James.Bottomley@HansenPartnership.com>
9 *
10 **-----------------------------------------------------------------------------
11 **
12 ** This program is free software; you can redistribute it and/or modify
13 ** it under the terms of the GNU General Public License as published by
14 ** the Free Software Foundation; either version 2 of the License, or
15 ** (at your option) any later version.
16 **
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ** GNU General Public License for more details.
21 **
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 **
26 **-----------------------------------------------------------------------------
27 */
29 #include <linux/module.h>
30 #include <linux/device.h>
31 #include <linux/mca.h>
32 #include <linux/string.h>
34 /**
35 * mca_device_read_stored_pos - read POS register from stored data
36 * @mca_dev: device to read from
37 * @reg: register to read from
38 *
39 * Fetch a POS value that was stored at boot time by the kernel
40 * when it scanned the MCA space. The register value is returned.
41 * Missing or invalid registers report 0.
42 */
43 unsigned char mca_device_read_stored_pos(struct mca_device *mca_dev, int reg)
44 {
45 if(reg < 0 || reg >= 8)
46 return 0;
48 return mca_dev->pos[reg];
49 }
50 EXPORT_SYMBOL(mca_device_read_stored_pos);
52 /**
53 * mca_device_read_pos - read POS register from card
54 * @mca_dev: device to read from
55 * @reg: register to read from
56 *
57 * Fetch a POS value directly from the hardware to obtain the
58 * current value. This is much slower than
59 * mca_device_read_stored_pos and may not be invoked from
60 * interrupt context. It handles the deep magic required for
61 * onboard devices transparently.
62 */
63 unsigned char mca_device_read_pos(struct mca_device *mca_dev, int reg)
64 {
65 struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
67 return mca_bus->f.mca_read_pos(mca_dev, reg);
69 return mca_dev->pos[reg];
70 }
71 EXPORT_SYMBOL(mca_device_read_pos);
74 /**
75 * mca_device_write_pos - read POS register from card
76 * @mca_dev: device to write pos register to
77 * @reg: register to write to
78 * @byte: byte to write to the POS registers
79 *
80 * Store a POS value directly to the hardware. You should not
81 * normally need to use this function and should have a very good
82 * knowledge of MCA bus before you do so. Doing this wrongly can
83 * damage the hardware.
84 *
85 * This function may not be used from interrupt context.
86 *
87 */
88 void mca_device_write_pos(struct mca_device *mca_dev, int reg,
89 unsigned char byte)
90 {
91 struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
93 mca_bus->f.mca_write_pos(mca_dev, reg, byte);
94 }
95 EXPORT_SYMBOL(mca_device_write_pos);
97 /**
98 * mca_device_transform_irq - transform the ADF obtained IRQ
99 * @mca_device: device whose irq needs transforming
100 * @irq: input irq from ADF
101 *
102 * MCA Adapter Definition Files (ADF) contain irq, ioport, memory
103 * etc. definitions. In systems with more than one bus, these need
104 * to be transformed through bus mapping functions to get the real
105 * system global quantities.
106 *
107 * This function transforms the interrupt number and returns the
108 * transformed system global interrupt
109 */
110 int mca_device_transform_irq(struct mca_device *mca_dev, int irq)
111 {
112 struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
114 return mca_bus->f.mca_transform_irq(mca_dev, irq);
115 }
116 EXPORT_SYMBOL(mca_device_transform_irq);
118 /**
119 * mca_device_transform_ioport - transform the ADF obtained I/O port
120 * @mca_device: device whose port needs transforming
121 * @ioport: input I/O port from ADF
122 *
123 * MCA Adapter Definition Files (ADF) contain irq, ioport, memory
124 * etc. definitions. In systems with more than one bus, these need
125 * to be transformed through bus mapping functions to get the real
126 * system global quantities.
127 *
128 * This function transforms the I/O port number and returns the
129 * transformed system global port number.
130 *
131 * This transformation can be assumed to be linear for port ranges.
132 */
133 int mca_device_transform_ioport(struct mca_device *mca_dev, int port)
134 {
135 struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
137 return mca_bus->f.mca_transform_ioport(mca_dev, port);
138 }
139 EXPORT_SYMBOL(mca_device_transform_ioport);
141 /**
142 * mca_device_transform_memory - transform the ADF obtained memory
143 * @mca_device: device whose memory region needs transforming
144 * @mem: memory region start from ADF
145 *
146 * MCA Adapter Definition Files (ADF) contain irq, ioport, memory
147 * etc. definitions. In systems with more than one bus, these need
148 * to be transformed through bus mapping functions to get the real
149 * system global quantities.
150 *
151 * This function transforms the memory region start and returns the
152 * transformed system global memory region (physical).
153 *
154 * This transformation can be assumed to be linear for region ranges.
155 */
156 void *mca_device_transform_memory(struct mca_device *mca_dev, void *mem)
157 {
158 struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent);
160 return mca_bus->f.mca_transform_memory(mca_dev, mem);
161 }
162 EXPORT_SYMBOL(mca_device_transform_memory);
165 /**
166 * mca_device_claimed - check if claimed by driver
167 * @mca_dev: device to check
168 *
169 * Returns 1 if the slot has been claimed by a driver
170 */
172 int mca_device_claimed(struct mca_device *mca_dev)
173 {
174 return mca_dev->driver_loaded;
175 }
176 EXPORT_SYMBOL(mca_device_claimed);
178 /**
179 * mca_device_set_claim - set the claim value of the driver
180 * @mca_dev: device to set value for
181 * @val: claim value to set (1 claimed, 0 unclaimed)
182 */
183 void mca_device_set_claim(struct mca_device *mca_dev, int val)
184 {
185 mca_dev->driver_loaded = val;
186 }
187 EXPORT_SYMBOL(mca_device_set_claim);
189 /**
190 * mca_device_status - get the status of the device
191 * @mca_device: device to get
192 *
193 * returns an enumeration of the device status:
194 *
195 * MCA_ADAPTER_NORMAL adapter is OK.
196 * MCA_ADAPTER_NONE no adapter at device (should never happen).
197 * MCA_ADAPTER_DISABLED adapter is disabled.
198 * MCA_ADAPTER_ERROR adapter cannot be initialised.
199 */
200 enum MCA_AdapterStatus mca_device_status(struct mca_device *mca_dev)
201 {
202 return mca_dev->status;
203 }
204 EXPORT_SYMBOL(mca_device_status);
206 /**
207 * mca_device_set_name - set the name of the device
208 * @mca_device: device to set the name of
209 * @name: name to set
210 */
211 void mca_device_set_name(struct mca_device *mca_dev, const char *name)
212 {
213 if(!mca_dev)
214 return;
216 strlcpy(mca_dev->name, name, sizeof(mca_dev->name));
217 }
218 EXPORT_SYMBOL(mca_device_set_name);