diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 12:03:55 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 12:03:55 -0400 |
| commit | 46ee9645094ad1eb5b4888882ecaa1fb87dcd2a3 (patch) | |
| tree | d0a48e993568b6a2415cfc21fc06eaa2fd886429 /kernel | |
| parent | fa5312d9e87e7222c6c384c4e930dc149bc1178d (diff) | |
| parent | 25f3a5a2854dce8b8413fd24cc9d5b9e3632be54 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6:
PM: PM QOS update fix
Freezer / cgroup freezer: Update stale locking comments
PM / platform_bus: Allow runtime PM by default
i2c: Fix bus-level power management callbacks
PM QOS update
PM / Hibernate: Fix block_io.c printk warning
PM / Hibernate: Group swap ops
PM / Hibernate: Move the first_sector out of swsusp_write
PM / Hibernate: Separate block_io
PM / Hibernate: Snapshot cleanup
FS / libfs: Implement simple_write_to_buffer
PM / Hibernate: document open(/dev/snapshot) side effects
PM / Runtime: Add sysfs debug files
PM: Improve device power management document
PM: Update device power management document
PM: Allow runtime_suspend methods to call pm_schedule_suspend()
PM: pm_wakeup - switch to using bool
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cgroup_freezer.c | 21 | ||||
| -rw-r--r-- | kernel/pm_qos_params.c | 218 | ||||
| -rw-r--r-- | kernel/power/Makefile | 3 | ||||
| -rw-r--r-- | kernel/power/block_io.c | 103 | ||||
| -rw-r--r-- | kernel/power/power.h | 27 | ||||
| -rw-r--r-- | kernel/power/snapshot.c | 145 | ||||
| -rw-r--r-- | kernel/power/swap.c | 333 | ||||
| -rw-r--r-- | kernel/power/user.c | 37 |
8 files changed, 456 insertions, 431 deletions
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index e5c0244962b0..ce71ed53e88f 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c | |||
| @@ -89,10 +89,10 @@ struct cgroup_subsys freezer_subsys; | |||
| 89 | 89 | ||
| 90 | /* Locks taken and their ordering | 90 | /* Locks taken and their ordering |
| 91 | * ------------------------------ | 91 | * ------------------------------ |
| 92 | * css_set_lock | ||
| 93 | * cgroup_mutex (AKA cgroup_lock) | 92 | * cgroup_mutex (AKA cgroup_lock) |
| 94 | * task->alloc_lock (AKA task_lock) | ||
| 95 | * freezer->lock | 93 | * freezer->lock |
| 94 | * css_set_lock | ||
| 95 | * task->alloc_lock (AKA task_lock) | ||
| 96 | * task->sighand->siglock | 96 | * task->sighand->siglock |
| 97 | * | 97 | * |
| 98 | * cgroup code forces css_set_lock to be taken before task->alloc_lock | 98 | * cgroup code forces css_set_lock to be taken before task->alloc_lock |
| @@ -100,33 +100,38 @@ struct cgroup_subsys freezer_subsys; | |||
| 100 | * freezer_create(), freezer_destroy(): | 100 | * freezer_create(), freezer_destroy(): |
| 101 | * cgroup_mutex [ by cgroup core ] | 101 | * cgroup_mutex [ by cgroup core ] |
| 102 | * | 102 | * |
| 103 | * can_attach(): | 103 | * freezer_can_attach(): |
| 104 | * cgroup_mutex | 104 | * cgroup_mutex (held by caller of can_attach) |
| 105 | * | 105 | * |
| 106 | * cgroup_frozen(): | 106 | * cgroup_freezing_or_frozen(): |
| 107 | * task->alloc_lock (to get task's cgroup) | 107 | * task->alloc_lock (to get task's cgroup) |
| 108 | * | 108 | * |
| 109 | * freezer_fork() (preserving fork() performance means can't take cgroup_mutex): | 109 | * freezer_fork() (preserving fork() performance means can't take cgroup_mutex): |
| 110 | * task->alloc_lock (to get task's cgroup) | ||
| 111 | * freezer->lock | 110 | * freezer->lock |
| 112 | * sighand->siglock (if the cgroup is freezing) | 111 | * sighand->siglock (if the cgroup is freezing) |
| 113 | * | 112 | * |
| 114 | * freezer_read(): | 113 | * freezer_read(): |
| 115 | * cgroup_mutex | 114 | * cgroup_mutex |
| 116 | * freezer->lock | 115 | * freezer->lock |
| 116 | * write_lock css_set_lock (cgroup iterator start) | ||
| 117 | * task->alloc_lock | ||
| 117 | * read_lock css_set_lock (cgroup iterator start) | 118 | * read_lock css_set_lock (cgroup iterator start) |
| 118 | * | 119 | * |
| 119 | * freezer_write() (freeze): | 120 | * freezer_write() (freeze): |
| 120 | * cgroup_mutex | 121 | * cgroup_mutex |
| 121 | * freezer->lock | 122 | * freezer->lock |
| 123 | * write_lock css_set_lock (cgroup iterator start) | ||
| 124 | * task->alloc_lock | ||
| 122 | * read_lock css_set_lock (cgroup iterator start) | 125 | * read_lock css_set_lock (cgroup iterator start) |
| 123 | * sighand->siglock | 126 | * sighand->siglock (fake signal delivery inside freeze_task()) |
| 124 | * | 127 | * |
| 125 | * freezer_write() (unfreeze): | 128 | * freezer_write() (unfreeze): |
| 126 | * cgroup_mutex | 129 | * cgroup_mutex |
| 127 | * freezer->lock | 130 | * freezer->lock |
| 131 | * write_lock css_set_lock (cgroup iterator start) | ||
| 132 | * task->alloc_lock | ||
| 128 | * read_lock css_set_lock (cgroup iterator start) | 133 | * read_lock css_set_lock (cgroup iterator start) |
| 129 | * task->alloc_lock (to prevent races with freeze_task()) | 134 | * task->alloc_lock (inside thaw_process(), prevents race with refrigerator()) |
| 130 | * sighand->siglock | 135 | * sighand->siglock |
| 131 | */ | 136 | */ |
| 132 | static struct cgroup_subsys_state *freezer_create(struct cgroup_subsys *ss, | 137 | static struct cgroup_subsys_state *freezer_create(struct cgroup_subsys *ss, |
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 3db49b9ca374..f42d3f737a33 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * This module exposes the interface to kernel space for specifying | 2 | * This module exposes the interface to kernel space for specifying |
| 3 | * QoS dependencies. It provides infrastructure for registration of: | 3 | * QoS dependencies. It provides infrastructure for registration of: |
| 4 | * | 4 | * |
| 5 | * Dependents on a QoS value : register requirements | 5 | * Dependents on a QoS value : register requests |
| 6 | * Watchers of QoS value : get notified when target QoS value changes | 6 | * Watchers of QoS value : get notified when target QoS value changes |
| 7 | * | 7 | * |
| 8 | * This QoS design is best effort based. Dependents register their QoS needs. | 8 | * This QoS design is best effort based. Dependents register their QoS needs. |
| @@ -14,19 +14,21 @@ | |||
| 14 | * timeout: usec <-- currently not used. | 14 | * timeout: usec <-- currently not used. |
| 15 | * throughput: kbs (kilo byte / sec) | 15 | * throughput: kbs (kilo byte / sec) |
| 16 | * | 16 | * |
| 17 | * There are lists of pm_qos_objects each one wrapping requirements, notifiers | 17 | * There are lists of pm_qos_objects each one wrapping requests, notifiers |
| 18 | * | 18 | * |
| 19 | * User mode requirements on a QOS parameter register themselves to the | 19 | * User mode requests on a QOS parameter register themselves to the |
| 20 | * subsystem by opening the device node /dev/... and writing there request to | 20 | * subsystem by opening the device node /dev/... and writing there request to |
| 21 | * the node. As long as the process holds a file handle open to the node the | 21 | * the node. As long as the process holds a file handle open to the node the |
| 22 | * client continues to be accounted for. Upon file release the usermode | 22 | * client continues to be accounted for. Upon file release the usermode |
| 23 | * requirement is removed and a new qos target is computed. This way when the | 23 | * request is removed and a new qos target is computed. This way when the |
| 24 | * requirement that the application has is cleaned up when closes the file | 24 | * request that the application has is cleaned up when closes the file |
| 25 | * pointer or exits the pm_qos_object will get an opportunity to clean up. | 25 | * pointer or exits the pm_qos_object will get an opportunity to clean up. |
| 26 | * | 26 | * |
| 27 | * Mark Gross <mgross@linux.intel.com> | 27 | * Mark Gross <mgross@linux.intel.com> |
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | /*#define DEBUG*/ | ||
| 31 | |||
| 30 | #include <linux/pm_qos_params.h> | 32 | #include <linux/pm_qos_params.h> |
| 31 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
| 32 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
| @@ -42,25 +44,25 @@ | |||
| 42 | #include <linux/uaccess.h> | 44 | #include <linux/uaccess.h> |
| 43 | 45 | ||
| 44 | /* | 46 | /* |
| 45 | * locking rule: all changes to requirements or notifiers lists | 47 | * locking rule: all changes to requests or notifiers lists |
| 46 | * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock | 48 | * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock |
| 47 | * held, taken with _irqsave. One lock to rule them all | 49 | * held, taken with _irqsave. One lock to rule them all |
| 48 | */ | 50 | */ |
| 49 | struct requirement_list { | 51 | struct pm_qos_request_list { |
| 50 | struct list_head list; | 52 | struct list_head list; |
| 51 | union { | 53 | union { |
| 52 | s32 value; | 54 | s32 value; |
| 53 | s32 usec; | 55 | s32 usec; |
| 54 | s32 kbps; | 56 | s32 kbps; |
| 55 | }; | 57 | }; |
| 56 | char *name; | 58 | int pm_qos_class; |
| 57 | }; | 59 | }; |
| 58 | 60 | ||
| 59 | static s32 max_compare(s32 v1, s32 v2); | 61 | static s32 max_compare(s32 v1, s32 v2); |
| 60 | static s32 min_compare(s32 v1, s32 v2); | 62 | static s32 min_compare(s32 v1, s32 v2); |
| 61 | 63 | ||
| 62 | struct pm_qos_object { | 64 | struct pm_qos_object { |
| 63 | struct requirement_list requirements; | 65 | struct pm_qos_request_list requests; |
| 64 | struct blocking_notifier_head *notifiers; | 66 | struct blocking_notifier_head *notifiers; |
| 65 | struct miscdevice pm_qos_power_miscdev; | 67 | struct miscdevice pm_qos_power_miscdev; |
| 66 | char *name; | 68 | char *name; |
| @@ -72,7 +74,7 @@ struct pm_qos_object { | |||
| 72 | static struct pm_qos_object null_pm_qos; | 74 | static struct pm_qos_object null_pm_qos; |
| 73 | static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier); | 75 | static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier); |
| 74 | static struct pm_qos_object cpu_dma_pm_qos = { | 76 | static struct pm_qos_object cpu_dma_pm_qos = { |
| 75 | .requirements = {LIST_HEAD_INIT(cpu_dma_pm_qos.requirements.list)}, | 77 | .requests = {LIST_HEAD_INIT(cpu_dma_pm_qos.requests.list)}, |
| 76 | .notifiers = &cpu_dma_lat_notifier, | 78 | .notifiers = &cpu_dma_lat_notifier, |
| 77 | .name = "cpu_dma_latency", | 79 | .name = "cpu_dma_latency", |
| 78 | .default_value = 2000 * USEC_PER_SEC, | 80 | .default_value = 2000 * USEC_PER_SEC, |
| @@ -82,7 +84,7 @@ static struct pm_qos_object cpu_dma_pm_qos = { | |||
| 82 | 84 | ||
| 83 | static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); | 85 | static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); |
| 84 | static struct pm_qos_object network_lat_pm_qos = { | 86 | static struct pm_qos_object network_lat_pm_qos = { |
| 85 | .requirements = {LIST_HEAD_INIT(network_lat_pm_qos.requirements.list)}, | ||
