ia64/linux-2.6.18-xen.hg

view drivers/acpi/pci_bind.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 /*
2 * pci_bind.c - ACPI PCI Device Binding ($Revision: 2 $)
3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/types.h>
30 #include <linux/proc_fs.h>
31 #include <linux/spinlock.h>
32 #include <linux/pm.h>
33 #include <linux/pci.h>
34 #include <linux/acpi.h>
35 #include <acpi/acpi_bus.h>
36 #include <acpi/acpi_drivers.h>
38 #define _COMPONENT ACPI_PCI_COMPONENT
39 ACPI_MODULE_NAME("pci_bind")
41 struct acpi_pci_data {
42 struct acpi_pci_id id;
43 struct pci_bus *bus;
44 struct pci_dev *dev;
45 };
47 static void acpi_pci_data_handler(acpi_handle handle, u32 function,
48 void *context)
49 {
51 /* TBD: Anything we need to do here? */
53 return;
54 }
56 /**
57 * acpi_get_pci_id
58 * ------------------
59 * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
60 * to resolve PCI information for ACPI-PCI devices defined in the namespace.
61 * This typically occurs when resolving PCI operation region information.
62 */
63 acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id)
64 {
65 int result = 0;
66 acpi_status status = AE_OK;
67 struct acpi_device *device = NULL;
68 struct acpi_pci_data *data = NULL;
71 if (!id)
72 return AE_BAD_PARAMETER;
74 result = acpi_bus_get_device(handle, &device);
75 if (result) {
76 printk(KERN_ERR PREFIX
77 "Invalid ACPI Bus context for device %s\n",
78 acpi_device_bid(device));
79 return AE_NOT_EXIST;
80 }
82 status = acpi_get_data(handle, acpi_pci_data_handler, (void **)&data);
83 if (ACPI_FAILURE(status) || !data) {
84 ACPI_EXCEPTION((AE_INFO, status,
85 "Invalid ACPI-PCI context for device %s",
86 acpi_device_bid(device)));
87 return status;
88 }
90 *id = data->id;
92 /*
93 id->segment = data->id.segment;
94 id->bus = data->id.bus;
95 id->device = data->id.device;
96 id->function = data->id.function;
97 */
99 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
100 "Device %s has PCI address %02x:%02x:%02x.%02x\n",
101 acpi_device_bid(device), id->segment, id->bus,
102 id->device, id->function));
104 return AE_OK;
105 }
107 EXPORT_SYMBOL(acpi_get_pci_id);
109 int acpi_pci_bind(struct acpi_device *device)
110 {
111 int result = 0;
112 acpi_status status = AE_OK;
113 struct acpi_pci_data *data = NULL;
114 struct acpi_pci_data *pdata = NULL;
115 char *pathname = NULL;
116 struct acpi_buffer buffer = { 0, NULL };
117 acpi_handle handle = NULL;
118 struct pci_dev *dev;
119 struct pci_bus *bus;
122 if (!device || !device->parent)
123 return -EINVAL;
125 pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
126 if (!pathname)
127 return -ENOMEM;
128 memset(pathname, 0, ACPI_PATHNAME_MAX);
129 buffer.length = ACPI_PATHNAME_MAX;
130 buffer.pointer = pathname;
132 data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
133 if (!data) {
134 kfree(pathname);
135 return -ENOMEM;
136 }
137 memset(data, 0, sizeof(struct acpi_pci_data));
139 acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
140 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n",
141 pathname));
143 /*
144 * Segment & Bus
145 * -------------
146 * These are obtained via the parent device's ACPI-PCI context.
147 */
148 status = acpi_get_data(device->parent->handle, acpi_pci_data_handler,
149 (void **)&pdata);
150 if (ACPI_FAILURE(status) || !pdata || !pdata->bus) {
151 ACPI_EXCEPTION((AE_INFO, status,
152 "Invalid ACPI-PCI context for parent device %s",
153 acpi_device_bid(device->parent)));
154 result = -ENODEV;
155 goto end;
156 }
157 data->id.segment = pdata->id.segment;
158 data->id.bus = pdata->bus->number;
160 /*
161 * Device & Function
162 * -----------------
163 * These are simply obtained from the device's _ADR method. Note
164 * that a value of zero is valid.
165 */
166 data->id.device = device->pnp.bus_address >> 16;
167 data->id.function = device->pnp.bus_address & 0xFFFF;
169 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %02x:%02x:%02x.%02x\n",
170 data->id.segment, data->id.bus, data->id.device,
171 data->id.function));
173 /*
174 * TBD: Support slot devices (e.g. function=0xFFFF).
175 */
177 /*
178 * Locate PCI Device
179 * -----------------
180 * Locate matching device in PCI namespace. If it doesn't exist
181 * this typically means that the device isn't currently inserted
182 * (e.g. docking station, port replicator, etc.).
183 * We cannot simply search the global pci device list, since
184 * PCI devices are added to the global pci list when the root
185 * bridge start ops are run, which may not have happened yet.
186 */
187 bus = pci_find_bus(data->id.segment, data->id.bus);
188 if (bus) {
189 list_for_each_entry(dev, &bus->devices, bus_list) {
190 if (dev->devfn == PCI_DEVFN(data->id.device,
191 data->id.function)) {
192 data->dev = dev;
193 break;
194 }
195 }
196 }
197 if (!data->dev) {
198 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
199 "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
200 data->id.segment, data->id.bus,
201 data->id.device, data->id.function));
202 result = -ENODEV;
203 goto end;
204 }
205 if (!data->dev->bus) {
206 printk(KERN_ERR PREFIX
207 "Device %02x:%02x:%02x.%02x has invalid 'bus' field\n",
208 data->id.segment, data->id.bus,
209 data->id.device, data->id.function);
210 result = -ENODEV;
211 goto end;
212 }
214 /*
215 * PCI Bridge?
216 * -----------
217 * If so, set the 'bus' field and install the 'bind' function to
218 * facilitate callbacks for all of its children.
219 */
220 if (data->dev->subordinate) {
221 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
222 "Device %02x:%02x:%02x.%02x is a PCI bridge\n",
223 data->id.segment, data->id.bus,
224 data->id.device, data->id.function));
225 data->bus = data->dev->subordinate;
226 device->ops.bind = acpi_pci_bind;
227 device->ops.unbind = acpi_pci_unbind;
228 }
230 /*
231 * Attach ACPI-PCI Context
232 * -----------------------
233 * Thus binding the ACPI and PCI devices.
234 */
235 status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
236 if (ACPI_FAILURE(status)) {
237 ACPI_EXCEPTION((AE_INFO, status,
238 "Unable to attach ACPI-PCI context to device %s",
239 acpi_device_bid(device)));
240 result = -ENODEV;
241 goto end;
242 }
244 /*
245 * PCI Routing Table
246 * -----------------
247 * Evaluate and parse _PRT, if exists. This code is independent of
248 * PCI bridges (above) to allow parsing of _PRT objects within the
249 * scope of non-bridge devices. Note that _PRTs within the scope of
250 * a PCI bridge assume the bridge's subordinate bus number.
251 *
252 * TBD: Can _PRTs exist within the scope of non-bridge PCI devices?
253 */
254 status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
255 if (ACPI_SUCCESS(status)) {
256 if (data->bus) /* PCI-PCI bridge */
257 acpi_pci_irq_add_prt(device->handle, data->id.segment,
258 data->bus->number);
259 else /* non-bridge PCI device */
260 acpi_pci_irq_add_prt(device->handle, data->id.segment,
261 data->id.bus);
262 }
264 end:
265 kfree(pathname);
266 if (result)
267 kfree(data);
269 return result;
270 }
272 int acpi_pci_unbind(struct acpi_device *device)
273 {
274 int result = 0;
275 acpi_status status = AE_OK;
276 struct acpi_pci_data *data = NULL;
277 char *pathname = NULL;
278 struct acpi_buffer buffer = { 0, NULL };
281 if (!device || !device->parent)
282 return -EINVAL;
284 pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
285 if (!pathname)
286 return -ENOMEM;
287 memset(pathname, 0, ACPI_PATHNAME_MAX);
289 buffer.length = ACPI_PATHNAME_MAX;
290 buffer.pointer = pathname;
291 acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
292 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n",
293 pathname));
294 kfree(pathname);
296 status =
297 acpi_get_data(device->handle, acpi_pci_data_handler,
298 (void **)&data);
299 if (ACPI_FAILURE(status)) {
300 ACPI_EXCEPTION((AE_INFO, status,
301 "Unable to get data from device %s",
302 acpi_device_bid(device)));
303 result = -ENODEV;
304 goto end;
305 }
307 status = acpi_detach_data(device->handle, acpi_pci_data_handler);
308 if (ACPI_FAILURE(status)) {
309 ACPI_EXCEPTION((AE_INFO, status,
310 "Unable to detach data from device %s",
311 acpi_device_bid(device)));
312 result = -ENODEV;
313 goto end;
314 }
315 if (data->dev->subordinate) {
316 acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
317 }
318 kfree(data);
320 end:
321 return result;
322 }
324 int
325 acpi_pci_bind_root(struct acpi_device *device,
326 struct acpi_pci_id *id, struct pci_bus *bus)
327 {
328 int result = 0;
329 acpi_status status = AE_OK;
330 struct acpi_pci_data *data = NULL;
331 char *pathname = NULL;
332 struct acpi_buffer buffer = { 0, NULL };
335 pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
336 if (!pathname)
337 return -ENOMEM;
338 memset(pathname, 0, ACPI_PATHNAME_MAX);
340 buffer.length = ACPI_PATHNAME_MAX;
341 buffer.pointer = pathname;
343 if (!device || !id || !bus) {
344 kfree(pathname);
345 return -EINVAL;
346 }
348 data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL);
349 if (!data) {
350 kfree(pathname);
351 return -ENOMEM;
352 }
353 memset(data, 0, sizeof(struct acpi_pci_data));
355 data->id = *id;
356 data->bus = bus;
357 device->ops.bind = acpi_pci_bind;
358 device->ops.unbind = acpi_pci_unbind;
360 acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer);
362 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to "
363 "%02x:%02x\n", pathname, id->segment, id->bus));
365 status = acpi_attach_data(device->handle, acpi_pci_data_handler, data);
366 if (ACPI_FAILURE(status)) {
367 ACPI_EXCEPTION((AE_INFO, status,
368 "Unable to attach ACPI-PCI context to device %s",
369 pathname));
370 result = -ENODEV;
371 goto end;
372 }
374 end:
375 kfree(pathname);
376 if (result != 0)
377 kfree(data);
379 return result;
380 }