diff options
Diffstat (limited to 'kernel/cgroup_freezer.c')
-rw-r--r-- | kernel/cgroup_freezer.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index 59e9ef6aab40..e5c0244962b0 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/slab.h> | ||
18 | #include <linux/cgroup.h> | 19 | #include <linux/cgroup.h> |
19 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
20 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
@@ -47,17 +48,20 @@ static inline struct freezer *task_freezer(struct task_struct *task) | |||
47 | struct freezer, css); | 48 | struct freezer, css); |
48 | } | 49 | } |
49 | 50 | ||
50 | int cgroup_frozen(struct task_struct *task) | 51 | int cgroup_freezing_or_frozen(struct task_struct *task) |
51 | { | 52 | { |
52 | struct freezer *freezer; | 53 | struct freezer *freezer; |
53 | enum freezer_state state; | 54 | enum freezer_state state; |
54 | 55 | ||
55 | task_lock(task); | 56 | task_lock(task); |
56 | freezer = task_freezer(task); | 57 | freezer = task_freezer(task); |
57 | state = freezer->state; | 58 | if (!freezer->css.cgroup->parent) |
59 | state = CGROUP_THAWED; /* root cgroup can't be frozen */ | ||
60 | else | ||
61 | state = freezer->state; | ||
58 | task_unlock(task); | 62 | task_unlock(task); |
59 | 63 | ||
60 | return state == CGROUP_FROZEN; | 64 | return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN); |
61 | } | 65 | } |
62 | 66 | ||
63 | /* | 67 | /* |
@@ -201,9 +205,12 @@ static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task) | |||
201 | * No lock is needed, since the task isn't on tasklist yet, | 205 | * No lock is needed, since the task isn't on tasklist yet, |
202 | * so it can't be moved to another cgroup, which means the | 206 | * so it can't be moved to another cgroup, which means the |
203 | * freezer won't be removed and will be valid during this | 207 | * freezer won't be removed and will be valid during this |
204 | * function call. | 208 | * function call. Nevertheless, apply RCU read-side critical |
209 | * section to suppress RCU lockdep false positives. | ||
205 | */ | 210 | */ |
211 | rcu_read_lock(); | ||
206 | freezer = task_freezer(task); | 212 | freezer = task_freezer(task); |
213 | rcu_read_unlock(); | ||
207 | 214 | ||
208 | /* | 215 | /* |
209 | * The root cgroup is non-freezable, so we can skip the | 216 | * The root cgroup is non-freezable, so we can skip the |