aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-11-21 15:32:25 -0500
committerTejun Heo <tj@kernel.org>2011-11-21 15:32:25 -0500
commita3201227f803ad7fd43180c5195dbe5a2bf998aa (patch)
tree1845ba06346f8a8772fe1c90f8960bd1a430d05c /kernel/power
parent22b4e111fa01a1147aa562ceaf18a752a928ef4e (diff)
freezer: make freezing() test freeze conditions in effect instead of TIF_FREEZE
Using TIF_FREEZE for freezing worked when there was only single freezing condition (the PM one); however, now there is also the cgroup_freezer and single bit flag is getting clumsy. thaw_processes() is already testing whether cgroup freezing in in effect to avoid thawing tasks which were frozen by both PM and cgroup freezers. This is racy (nothing prevents race against cgroup freezing) and fragile. A much simpler way is to test actual freeze conditions from freezing() - ie. directly test whether PM or cgroup freezing is in effect. This patch adds variables to indicate whether and what type of freezing conditions are in effect and reimplements freezing() such that it directly tests whether any of the two freezing conditions is active and the task should freeze. On fast path, freezing() is still very cheap - it only tests system_freezing_cnt. This makes the clumsy dancing aroung TIF_FREEZE unnecessary and freeze/thaw operations more usual - updating state variables for the new state and nudging target tasks so that they notice the new state and comply. As long as the nudging happens after state update, it's race-free. * This allows use of freezing() in freeze_task(). Replace the open coded tests with freezing(). * p != current test is added to warning printing conditions in try_to_freeze_tasks() failure path. This is necessary as freezing() is now true for the task which initiated freezing too. -v2: Oleg pointed out that re-freezing FROZEN cgroup could increment system_freezing_cnt. Fixed. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Paul Menage <paul@paulmenage.org> (for the cgroup portions)
Diffstat (limited to 'kernel/power')
-rw-r--r--kernel/power/process.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 9f6f5c755cfa..0beb51e1dec9 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -101,7 +101,7 @@ static int try_to_freeze_tasks(bool sig_only)
101 read_lock(&tasklist_lock); 101 read_lock(&tasklist_lock);
102 do_each_thread(g, p) { 102 do_each_thread(g, p) {
103 if (!wakeup && !freezer_should_skip(p) && 103 if (!wakeup && !freezer_should_skip(p) &&
104 freezing(p) && !frozen(p)) 104 p != current && freezing(p) && !frozen(p))
105 sched_show_task(p); 105 sched_show_task(p);
106 } while_each_thread(g, p); 106 } while_each_thread(g, p);
107 read_unlock(&tasklist_lock); 107 read_unlock(&tasklist_lock);
@@ -122,7 +122,11 @@ int freeze_processes(void)
122{ 122{
123 int error; 123 int error;
124 124
125 if (!pm_freezing)
126 atomic_inc(&system_freezing_cnt);
127
125 printk("Freezing user space processes ... "); 128 printk("Freezing user space processes ... ");
129 pm_freezing = true;
126 error = try_to_freeze_tasks(true); 130 error = try_to_freeze_tasks(true);
127 if (!error) { 131 if (!error) {
128 printk("done."); 132 printk("done.");
@@ -146,6 +150,7 @@ int freeze_kernel_threads(void)
146 int error; 150 int error;
147 151
148 printk("Freezing remaining freezable tasks ... "); 152 printk("Freezing remaining freezable tasks ... ");
153 pm_nosig_freezing = true;
149 error = try_to_freeze_tasks(false); 154 error = try_to_freeze_tasks(false);
150 if (!error) 155 if (!error)
151 printk("done."); 156 printk("done.");
@@ -162,6 +167,11 @@ void thaw_processes(void)
162{ 167{
163 struct task_struct *g, *p; 168 struct task_struct *g, *p;
164 169
170 if (pm_freezing)
171 atomic_dec(&system_freezing_cnt);
172 pm_freezing = false;
173 pm_nosig_freezing = false;
174
165 oom_killer_enable(); 175 oom_killer_enable();
166 176
167 printk("Restarting tasks ... "); 177 printk("Restarting tasks ... ");
@@ -170,9 +180,6 @@ void thaw_processes(void)
170 180
171 read_lock(&tasklist_lock); 181 read_lock(&tasklist_lock);
172 do_each_thread(g, p) { 182 do_each_thread(g, p) {
173 if (cgroup_freezing(p))
174 continue;
175
176 __thaw_task(p); 183 __thaw_task(p);
177 } while_each_thread(g, p); 184 } while_each_thread(g, p);
178 read_unlock(&tasklist_lock); 185 read_unlock(&tasklist_lock);