ia64/linux-2.6.18-xen.hg

view drivers/acpi/dock.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 * dock.c - ACPI dock station driver
3 *
4 * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/types.h>
29 #include <linux/notifier.h>
30 #include <acpi/acpi_bus.h>
31 #include <acpi/acpi_drivers.h>
33 #define ACPI_DOCK_DRIVER_NAME "ACPI Dock Station Driver"
35 ACPI_MODULE_NAME("dock")
36 MODULE_AUTHOR("Kristen Carlson Accardi");
37 MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME);
38 MODULE_LICENSE("GPL");
40 static struct atomic_notifier_head dock_notifier_list;
42 struct dock_station {
43 acpi_handle handle;
44 unsigned long last_dock_time;
45 u32 flags;
46 spinlock_t dd_lock;
47 spinlock_t hp_lock;
48 struct list_head dependent_devices;
49 struct list_head hotplug_devices;
50 };
52 struct dock_dependent_device {
53 struct list_head list;
54 struct list_head hotplug_list;
55 acpi_handle handle;
56 acpi_notify_handler handler;
57 void *context;
58 };
60 #define DOCK_DOCKING 0x00000001
61 #define DOCK_EVENT 3
62 #define UNDOCK_EVENT 2
64 static struct dock_station *dock_station;
66 /*****************************************************************************
67 * Dock Dependent device functions *
68 *****************************************************************************/
69 /**
70 * alloc_dock_dependent_device - allocate and init a dependent device
71 * @handle: the acpi_handle of the dependent device
72 *
73 * Allocate memory for a dependent device structure for a device referenced
74 * by the acpi handle
75 */
76 static struct dock_dependent_device *
77 alloc_dock_dependent_device(acpi_handle handle)
78 {
79 struct dock_dependent_device *dd;
81 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
82 if (dd) {
83 dd->handle = handle;
84 INIT_LIST_HEAD(&dd->list);
85 INIT_LIST_HEAD(&dd->hotplug_list);
86 }
87 return dd;
88 }
90 /**
91 * add_dock_dependent_device - associate a device with the dock station
92 * @ds: The dock station
93 * @dd: The dependent device
94 *
95 * Add the dependent device to the dock's dependent device list.
96 */
97 static void
98 add_dock_dependent_device(struct dock_station *ds,
99 struct dock_dependent_device *dd)
100 {
101 spin_lock(&ds->dd_lock);
102 list_add_tail(&dd->list, &ds->dependent_devices);
103 spin_unlock(&ds->dd_lock);
104 }
106 /**
107 * dock_add_hotplug_device - associate a hotplug handler with the dock station
108 * @ds: The dock station
109 * @dd: The dependent device struct
110 *
111 * Add the dependent device to the dock's hotplug device list
112 */
113 static void
114 dock_add_hotplug_device(struct dock_station *ds,
115 struct dock_dependent_device *dd)
116 {
117 spin_lock(&ds->hp_lock);
118 list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
119 spin_unlock(&ds->hp_lock);
120 }
122 /**
123 * dock_del_hotplug_device - remove a hotplug handler from the dock station
124 * @ds: The dock station
125 * @dd: the dependent device struct
126 *
127 * Delete the dependent device from the dock's hotplug device list
128 */
129 static void
130 dock_del_hotplug_device(struct dock_station *ds,
131 struct dock_dependent_device *dd)
132 {
133 spin_lock(&ds->hp_lock);
134 list_del(&dd->hotplug_list);
135 spin_unlock(&ds->hp_lock);
136 }
138 /**
139 * find_dock_dependent_device - get a device dependent on this dock
140 * @ds: the dock station
141 * @handle: the acpi_handle of the device we want
142 *
143 * iterate over the dependent device list for this dock. If the
144 * dependent device matches the handle, return.
145 */
146 static struct dock_dependent_device *
147 find_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
148 {
149 struct dock_dependent_device *dd;
151 spin_lock(&ds->dd_lock);
152 list_for_each_entry(dd, &ds->dependent_devices, list) {
153 if (handle == dd->handle) {
154 spin_unlock(&ds->dd_lock);
155 return dd;
156 }
157 }
158 spin_unlock(&ds->dd_lock);
159 return NULL;
160 }
162 /*****************************************************************************
163 * Dock functions *
164 *****************************************************************************/
165 /**
166 * is_dock - see if a device is a dock station
167 * @handle: acpi handle of the device
168 *
169 * If an acpi object has a _DCK method, then it is by definition a dock
170 * station, so return true.
171 */
172 static int is_dock(acpi_handle handle)
173 {
174 acpi_status status;
175 acpi_handle tmp;
177 status = acpi_get_handle(handle, "_DCK", &tmp);
178 if (ACPI_FAILURE(status))
179 return 0;
180 return 1;
181 }
183 /**
184 * is_dock_device - see if a device is on a dock station
185 * @handle: acpi handle of the device
186 *
187 * If this device is either the dock station itself,
188 * or is a device dependent on the dock station, then it
189 * is a dock device
190 */
191 int is_dock_device(acpi_handle handle)
192 {
193 if (!dock_station)
194 return 0;
196 if (is_dock(handle) || find_dock_dependent_device(dock_station, handle))
197 return 1;
199 return 0;
200 }
202 EXPORT_SYMBOL_GPL(is_dock_device);
204 /**
205 * dock_present - see if the dock station is present.
206 * @ds: the dock station
207 *
208 * execute the _STA method. note that present does not
209 * imply that we are docked.
210 */
211 static int dock_present(struct dock_station *ds)
212 {
213 unsigned long sta;
214 acpi_status status;
216 if (ds) {
217 status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta);
218 if (ACPI_SUCCESS(status) && sta)
219 return 1;
220 }
221 return 0;
222 }
226 /**
227 * dock_create_acpi_device - add new devices to acpi
228 * @handle - handle of the device to add
229 *
230 * This function will create a new acpi_device for the given
231 * handle if one does not exist already. This should cause
232 * acpi to scan for drivers for the given devices, and call
233 * matching driver's add routine.
234 *
235 * Returns a pointer to the acpi_device corresponding to the handle.
236 */
237 static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
238 {
239 struct acpi_device *device = NULL;
240 struct acpi_device *parent_device;
241 acpi_handle parent;
242 int ret;
244 if (acpi_bus_get_device(handle, &device)) {
245 /*
246 * no device created for this object,
247 * so we should create one.
248 */
249 acpi_get_parent(handle, &parent);
250 if (acpi_bus_get_device(parent, &parent_device))
251 parent_device = NULL;
253 ret = acpi_bus_add(&device, parent_device, handle,
254 ACPI_BUS_TYPE_DEVICE);
255 if (ret) {
256 pr_debug("error adding bus, %x\n",
257 -ret);
258 return NULL;
259 }
260 }
261 return device;
262 }
264 /**
265 * dock_remove_acpi_device - remove the acpi_device struct from acpi
266 * @handle - the handle of the device to remove
267 *
268 * Tell acpi to remove the acpi_device. This should cause any loaded
269 * driver to have it's remove routine called.
270 */
271 static void dock_remove_acpi_device(acpi_handle handle)
272 {
273 struct acpi_device *device;
274 int ret;
276 if (!acpi_bus_get_device(handle, &device)) {
277 ret = acpi_bus_trim(device, 1);
278 if (ret)
279 pr_debug("error removing bus, %x\n", -ret);
280 }
281 }
284 /**
285 * hotplug_dock_devices - insert or remove devices on the dock station
286 * @ds: the dock station
287 * @event: either bus check or eject request
288 *
289 * Some devices on the dock station need to have drivers called
290 * to perform hotplug operations after a dock event has occurred.
291 * Traverse the list of dock devices that have registered a
292 * hotplug handler, and call the handler.
293 */
294 static void hotplug_dock_devices(struct dock_station *ds, u32 event)
295 {
296 struct dock_dependent_device *dd;
298 spin_lock(&ds->hp_lock);
300 /*
301 * First call driver specific hotplug functions
302 */
303 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
304 if (dd->handler)
305 dd->handler(dd->handle, event, dd->context);
306 }
308 /*
309 * Now make sure that an acpi_device is created for each
310 * dependent device, or removed if this is an eject request.
311 * This will cause acpi_drivers to be stopped/started if they
312 * exist
313 */
314 list_for_each_entry(dd, &ds->dependent_devices, list) {
315 if (event == ACPI_NOTIFY_EJECT_REQUEST)
316 dock_remove_acpi_device(dd->handle);
317 else
318 dock_create_acpi_device(dd->handle);
319 }
320 spin_unlock(&ds->hp_lock);
321 }
323 static void dock_event(struct dock_station *ds, u32 event, int num)
324 {
325 /*
326 * we don't do events until someone tells me that
327 * they would like to have them.
328 */
329 }
331 /**
332 * eject_dock - respond to a dock eject request
333 * @ds: the dock station
334 *
335 * This is called after _DCK is called, to execute the dock station's
336 * _EJ0 method.
337 */
338 static void eject_dock(struct dock_station *ds)
339 {
340 struct acpi_object_list arg_list;
341 union acpi_object arg;
342 acpi_status status;
343 acpi_handle tmp;
345 /* all dock devices should have _EJ0, but check anyway */
346 status = acpi_get_handle(ds->handle, "_EJ0", &tmp);
347 if (ACPI_FAILURE(status)) {
348 pr_debug("No _EJ0 support for dock device\n");
349 return;
350 }
352 arg_list.count = 1;
353 arg_list.pointer = &arg;
354 arg.type = ACPI_TYPE_INTEGER;
355 arg.integer.value = 1;
357 if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0",
358 &arg_list, NULL)))
359 pr_debug("Failed to evaluate _EJ0!\n");
360 }
362 /**
363 * handle_dock - handle a dock event
364 * @ds: the dock station
365 * @dock: to dock, or undock - that is the question
366 *
367 * Execute the _DCK method in response to an acpi event
368 */
369 static void handle_dock(struct dock_station *ds, int dock)
370 {
371 acpi_status status;
372 struct acpi_object_list arg_list;
373 union acpi_object arg;
374 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
375 struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
376 union acpi_object *obj;
378 acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer);
379 obj = name_buffer.pointer;
381 printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking");
383 /* _DCK method has one argument */
384 arg_list.count = 1;
385 arg_list.pointer = &arg;
386 arg.type = ACPI_TYPE_INTEGER;
387 arg.integer.value = dock;
388 status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
389 if (ACPI_FAILURE(status))
390 pr_debug("%s: failed to execute _DCK\n", obj->string.pointer);
391 kfree(buffer.pointer);
392 kfree(name_buffer.pointer);
393 }
395 static inline void dock(struct dock_station *ds)
396 {
397 handle_dock(ds, 1);
398 }
400 static inline void undock(struct dock_station *ds)
401 {
402 handle_dock(ds, 0);
403 }
405 static inline void begin_dock(struct dock_station *ds)
406 {
407 ds->flags |= DOCK_DOCKING;
408 }
410 static inline void complete_dock(struct dock_station *ds)
411 {
412 ds->flags &= ~(DOCK_DOCKING);
413 ds->last_dock_time = jiffies;
414 }
416 /**
417 * dock_in_progress - see if we are in the middle of handling a dock event
418 * @ds: the dock station
419 *
420 * Sometimes while docking, false dock events can be sent to the driver
421 * because good connections aren't made or some other reason. Ignore these
422 * if we are in the middle of doing something.
423 */
424 static int dock_in_progress(struct dock_station *ds)
425 {
426 if ((ds->flags & DOCK_DOCKING) ||
427 time_before(jiffies, (ds->last_dock_time + HZ)))
428 return 1;
429 return 0;
430 }
432 /**
433 * register_dock_notifier - add yourself to the dock notifier list
434 * @nb: the callers notifier block
435 *
436 * If a driver wishes to be notified about dock events, they can
437 * use this function to put a notifier block on the dock notifier list.
438 * this notifier call chain will be called after a dock event, but
439 * before hotplugging any new devices.
440 */
441 int register_dock_notifier(struct notifier_block *nb)
442 {
443 return atomic_notifier_chain_register(&dock_notifier_list, nb);
444 }
446 EXPORT_SYMBOL_GPL(register_dock_notifier);
448 /**
449 * unregister_dock_notifier - remove yourself from the dock notifier list
450 * @nb: the callers notifier block
451 */
452 void unregister_dock_notifier(struct notifier_block *nb)
453 {
454 atomic_notifier_chain_unregister(&dock_notifier_list, nb);
455 }
457 EXPORT_SYMBOL_GPL(unregister_dock_notifier);
459 /**
460 * register_hotplug_dock_device - register a hotplug function
461 * @handle: the handle of the device
462 * @handler: the acpi_notifier_handler to call after docking
463 * @context: device specific data
464 *
465 * If a driver would like to perform a hotplug operation after a dock
466 * event, they can register an acpi_notifiy_handler to be called by
467 * the dock driver after _DCK is executed.
468 */
469 int
470 register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
471 void *context)
472 {
473 struct dock_dependent_device *dd;
475 if (!dock_station)
476 return -ENODEV;
478 /*
479 * make sure this handle is for a device dependent on the dock,
480 * this would include the dock station itself
481 */
482 dd = find_dock_dependent_device(dock_station, handle);
483 if (dd) {
484 dd->handler = handler;
485 dd->context = context;
486 dock_add_hotplug_device(dock_station, dd);
487 return 0;
488 }
490 return -EINVAL;
491 }
493 EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
495 /**
496 * unregister_hotplug_dock_device - remove yourself from the hotplug list
497 * @handle: the acpi handle of the device
498 */
499 void unregister_hotplug_dock_device(acpi_handle handle)
500 {
501 struct dock_dependent_device *dd;
503 if (!dock_station)
504 return;
506 dd = find_dock_dependent_device(dock_station, handle);
507 if (dd)
508 dock_del_hotplug_device(dock_station, dd);
509 }
511 EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
513 /**
514 * dock_notify - act upon an acpi dock notification
515 * @handle: the dock station handle
516 * @event: the acpi event
517 * @data: our driver data struct
518 *
519 * If we are notified to dock, then check to see if the dock is
520 * present and then dock. Notify all drivers of the dock event,
521 * and then hotplug and devices that may need hotplugging. For undock
522 * check to make sure the dock device is still present, then undock
523 * and hotremove all the devices that may need removing.
524 */
525 static void dock_notify(acpi_handle handle, u32 event, void *data)
526 {
527 struct dock_station *ds = (struct dock_station *)data;
529 switch (event) {
530 case ACPI_NOTIFY_BUS_CHECK:
531 if (!dock_in_progress(ds) && dock_present(ds)) {
532 begin_dock(ds);
533 dock(ds);
534 if (!dock_present(ds)) {
535 printk(KERN_ERR PREFIX "Unable to dock!\n");
536 break;
537 }
538 atomic_notifier_call_chain(&dock_notifier_list,
539 event, NULL);
540 hotplug_dock_devices(ds, event);
541 complete_dock(ds);
542 dock_event(ds, event, DOCK_EVENT);
543 }
544 break;
545 case ACPI_NOTIFY_DEVICE_CHECK:
546 /*
547 * According to acpi spec 3.0a, if a DEVICE_CHECK notification
548 * is sent and _DCK is present, it is assumed to mean an
549 * undock request. This notify routine will only be called
550 * for objects defining _DCK, so we will fall through to eject
551 * request here. However, we will pass an eject request through
552 * to the driver who wish to hotplug.
553 */
554 case ACPI_NOTIFY_EJECT_REQUEST:
555 if (!dock_in_progress(ds) && dock_present(ds)) {
556 /*
557 * here we need to generate the undock
558 * event prior to actually doing the undock
559 * so that the device struct still exists.
560 */
561 dock_event(ds, event, UNDOCK_EVENT);
562 hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
563 undock(ds);
564 eject_dock(ds);
565 if (dock_present(ds))
566 printk(KERN_ERR PREFIX "Unable to undock!\n");
567 }
568 break;
569 default:
570 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
571 }
572 }
574 /**
575 * find_dock_devices - find devices on the dock station
576 * @handle: the handle of the device we are examining
577 * @lvl: unused
578 * @context: the dock station private data
579 * @rv: unused
580 *
581 * This function is called by acpi_walk_namespace. It will
582 * check to see if an object has an _EJD method. If it does, then it
583 * will see if it is dependent on the dock station.
584 */
585 static acpi_status
586 find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
587 {
588 acpi_status status;
589 acpi_handle tmp;
590 struct dock_station *ds = (struct dock_station *)context;
591 struct dock_dependent_device *dd;
593 status = acpi_bus_get_ejd(handle, &tmp);
594 if (ACPI_FAILURE(status))
595 return AE_OK;
597 if (tmp == ds->handle) {
598 dd = alloc_dock_dependent_device(handle);
599 if (dd)
600 add_dock_dependent_device(ds, dd);
601 }
603 return AE_OK;
604 }
606 /**
607 * dock_add - add a new dock station
608 * @handle: the dock station handle
609 *
610 * allocated and initialize a new dock station device. Find all devices
611 * that are on the dock station, and register for dock event notifications.
612 */
613 static int dock_add(acpi_handle handle)
614 {
615 int ret;
616 acpi_status status;
617 struct dock_dependent_device *dd;
619 /* allocate & initialize the dock_station private data */
620 dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL);
621 if (!dock_station)
622 return -ENOMEM;
623 dock_station->handle = handle;
624 dock_station->last_dock_time = jiffies - HZ;
625 INIT_LIST_HEAD(&dock_station->dependent_devices);
626 INIT_LIST_HEAD(&dock_station->hotplug_devices);
627 spin_lock_init(&dock_station->dd_lock);
628 spin_lock_init(&dock_station->hp_lock);
629 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
631 /* Find dependent devices */
632 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
633 ACPI_UINT32_MAX, find_dock_devices, dock_station,
634 NULL);
636 /* add the dock station as a device dependent on itself */
637 dd = alloc_dock_dependent_device(handle);
638 if (!dd) {
639 kfree(dock_station);
640 return -ENOMEM;
641 }
642 add_dock_dependent_device(dock_station, dd);
644 /* register for dock events */
645 status = acpi_install_notify_handler(dock_station->handle,
646 ACPI_SYSTEM_NOTIFY,
647 dock_notify, dock_station);
649 if (ACPI_FAILURE(status)) {
650 printk(KERN_ERR PREFIX "Error installing notify handler\n");
651 ret = -ENODEV;
652 goto dock_add_err;
653 }
655 printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_NAME);
657 return 0;
659 dock_add_err:
660 kfree(dock_station);
661 kfree(dd);
662 return ret;
663 }
665 /**
666 * dock_remove - free up resources related to the dock station
667 */
668 static int dock_remove(void)
669 {
670 struct dock_dependent_device *dd, *tmp;
671 acpi_status status;
673 if (!dock_station)
674 return 0;
676 /* remove dependent devices */
677 list_for_each_entry_safe(dd, tmp, &dock_station->dependent_devices,
678 list)
679 kfree(dd);
681 /* remove dock notify handler */
682 status = acpi_remove_notify_handler(dock_station->handle,
683 ACPI_SYSTEM_NOTIFY,
684 dock_notify);
685 if (ACPI_FAILURE(status))
686 printk(KERN_ERR "Error removing notify handler\n");
688 /* free dock station memory */
689 kfree(dock_station);
690 return 0;
691 }
693 /**
694 * find_dock - look for a dock station
695 * @handle: acpi handle of a device
696 * @lvl: unused
697 * @context: counter of dock stations found
698 * @rv: unused
699 *
700 * This is called by acpi_walk_namespace to look for dock stations.
701 */
702 static acpi_status
703 find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
704 {
705 int *count = (int *)context;
706 acpi_status status = AE_OK;
708 if (is_dock(handle)) {
709 if (dock_add(handle) >= 0) {
710 (*count)++;
711 status = AE_CTRL_TERMINATE;
712 }
713 }
714 return status;
715 }
717 static int __init dock_init(void)
718 {
719 int num = 0;
721 dock_station = NULL;
723 /* look for a dock station */
724 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
725 ACPI_UINT32_MAX, find_dock, &num, NULL);
727 if (!num)
728 return -ENODEV;
730 return 0;
731 }
733 static void __exit dock_exit(void)
734 {
735 dock_remove();
736 }
738 postcore_initcall(dock_init);
739 module_exit(dock_exit);