]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
cgroup_freezer: prepare for removal of TIF_FREEZE
authorTejun Heo <tj@kernel.org>
Sat, 20 Aug 2011 09:31:40 +0000 (11:31 +0200)
committerTejun Heo <tj@kernel.org>
Sat, 20 Aug 2011 09:31:40 +0000 (11:31 +0200)
TIF_FREEZE will be removed soon and freezing() will directly test
whether any freezing condition is in effect.  Make the following
changes in preparation.

* Rename cgroup_freezing_or_frozen() to cgroup_freezing() and make it
  return bool.

* Make cgroup_freezing() access task_freezer() under rcu read lock
  instead of task_lock().  This makes the state dereferencing racy
  against task moving to another cgroup; however, it was already racy
  without this change as ->state dereference wasn't synchronized.
  This will be later dealt with using attach hooks.

* freezer->state is now set before trying to push tasks into the
  target state.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Paul Menage <paul@paulmenage.org>
Cc: Li Zefan <lizf@cn.fujitsu.com>
include/linux/freezer.h
kernel/cgroup_freezer.c
kernel/power/process.c

index 13559a8080982330450480de1c83f86aadaab014..bcc0637f478c1d125fa35ff449b1b91d124efbc0 100644 (file)
@@ -63,11 +63,11 @@ extern bool freeze_task(struct task_struct *p, bool sig_only);
 extern bool __set_freezable(bool with_signal);
 
 #ifdef CONFIG_CGROUP_FREEZER
-extern int cgroup_freezing_or_frozen(struct task_struct *task);
+extern bool cgroup_freezing(struct task_struct *task);
 #else /* !CONFIG_CGROUP_FREEZER */
-static inline int cgroup_freezing_or_frozen(struct task_struct *task)
+static inline bool cgroup_freezing(struct task_struct *task)
 {
-       return 0;
+       return false;
 }
 #endif /* !CONFIG_CGROUP_FREEZER */
 
index e7fa0ec0690e5ece388679fbdaef5a41a9992d0a..0478c354cb218d1f5183180246b7fff5be0ed803 100644 (file)
@@ -48,19 +48,17 @@ static inline struct freezer *task_freezer(struct task_struct *task)
                            struct freezer, css);
 }
 
-static inline int __cgroup_freezing_or_frozen(struct task_struct *task)
+bool cgroup_freezing(struct task_struct *task)
 {
-       enum freezer_state state = task_freezer(task)->state;
-       return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN);
-}
+       enum freezer_state state;
+       bool ret;
 
-int cgroup_freezing_or_frozen(struct task_struct *task)
-{
-       int result;
-       task_lock(task);
-       result = __cgroup_freezing_or_frozen(task);
-       task_unlock(task);
-       return result;
+       rcu_read_lock();
+       state = task_freezer(task)->state;
+       ret = state == CGROUP_FREEZING || state == CGROUP_FROZEN;
+       rcu_read_unlock();
+
+       return ret;
 }
 
 /*
@@ -102,9 +100,6 @@ struct cgroup_subsys freezer_subsys;
  * freezer_can_attach():
  * cgroup_mutex (held by caller of can_attach)
  *
- * cgroup_freezing_or_frozen():
- * task->alloc_lock (to get task's cgroup)
- *
  * freezer_fork() (preserving fork() performance means can't take cgroup_mutex):
  * freezer->lock
  *  sighand->siglock (if the cgroup is freezing)
@@ -177,13 +172,7 @@ static int freezer_can_attach(struct cgroup_subsys *ss,
 
 static int freezer_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 {
-       rcu_read_lock();
-       if (__cgroup_freezing_or_frozen(tsk)) {
-               rcu_read_unlock();
-               return -EBUSY;
-       }
-       rcu_read_unlock();
-       return 0;
+       return cgroup_freezing(tsk) ? -EBUSY : 0;
 }
 
 static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task)
@@ -279,7 +268,6 @@ static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
        struct task_struct *task;
        unsigned int num_cant_freeze_now = 0;
 
-       freezer->state = CGROUP_FREEZING;
        cgroup_iter_start(cgroup, &it);
        while ((task = cgroup_iter_next(cgroup, &it))) {
                if (!freeze_task(task, true))
@@ -303,8 +291,6 @@ static void unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
        while ((task = cgroup_iter_next(cgroup, &it)))
                __thaw_task(task);
        cgroup_iter_end(cgroup, &it);
-
-       freezer->state = CGROUP_THAWED;
 }
 
 static int freezer_change_state(struct cgroup *cgroup,
@@ -321,6 +307,8 @@ static int freezer_change_state(struct cgroup *cgroup,
        if (goal_state == freezer->state)
                goto out;
 
+       freezer->state = goal_state;
+
        switch (goal_state) {
        case CGROUP_THAWED:
                unfreeze_cgroup(cgroup, freezer);
index f8012f2f5cdf30d774dd1780e2b2a9ebb4d353a1..1bbc363df4a9a6918987e379fb7051194963c824 100644 (file)
@@ -154,7 +154,7 @@ void thaw_processes(void)
 
        read_lock(&tasklist_lock);
        do_each_thread(g, p) {
-               if (cgroup_freezing_or_frozen(p))
+               if (cgroup_freezing(p))
                        continue;
 
                __thaw_task(p);