diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 2ce28f165e31..e7c181454dca 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/capability.h> | 30 | #include <linux/capability.h> |
31 | #include <linux/cpu.h> | 31 | #include <linux/cpu.h> |
32 | #include <linux/cpuset.h> | 32 | #include <linux/cpuset.h> |
33 | #include <linux/cgroup.h> | ||
33 | #include <linux/security.h> | 34 | #include <linux/security.h> |
34 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
35 | #include <linux/syscalls.h> | 36 | #include <linux/syscalls.h> |
@@ -979,6 +980,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
979 | { | 980 | { |
980 | int retval; | 981 | int retval; |
981 | struct task_struct *p = NULL; | 982 | struct task_struct *p = NULL; |
983 | int cgroup_callbacks_done = 0; | ||
982 | 984 | ||
983 | if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) | 985 | if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) |
984 | return ERR_PTR(-EINVAL); | 986 | return ERR_PTR(-EINVAL); |
@@ -1088,12 +1090,13 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1088 | p->io_context = NULL; | 1090 | p->io_context = NULL; |
1089 | p->audit_context = NULL; | 1091 | p->audit_context = NULL; |
1090 | cpuset_fork(p); | 1092 | cpuset_fork(p); |
1093 | cgroup_fork(p); | ||
1091 | #ifdef CONFIG_NUMA | 1094 | #ifdef CONFIG_NUMA |
1092 | p->mempolicy = mpol_copy(p->mempolicy); | 1095 | p->mempolicy = mpol_copy(p->mempolicy); |
1093 | if (IS_ERR(p->mempolicy)) { | 1096 | if (IS_ERR(p->mempolicy)) { |
1094 | retval = PTR_ERR(p->mempolicy); | 1097 | retval = PTR_ERR(p->mempolicy); |
1095 | p->mempolicy = NULL; | 1098 | p->mempolicy = NULL; |
1096 | goto bad_fork_cleanup_cpuset; | 1099 | goto bad_fork_cleanup_cgroup; |
1097 | } | 1100 | } |
1098 | mpol_fix_fork_child_flag(p); | 1101 | mpol_fix_fork_child_flag(p); |
1099 | #endif | 1102 | #endif |
@@ -1204,6 +1207,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1204 | /* Perform scheduler related setup. Assign this task to a CPU. */ | 1207 | /* Perform scheduler related setup. Assign this task to a CPU. */ |
1205 | sched_fork(p, clone_flags); | 1208 | sched_fork(p, clone_flags); |
1206 | 1209 | ||
1210 | /* Now that the task is set up, run cgroup callbacks if | ||
1211 | * necessary. We need to run them before the task is visible | ||
1212 | * on the tasklist. */ | ||
1213 | cgroup_fork_callbacks(p); | ||
1214 | cgroup_callbacks_done = 1; | ||
1215 | |||
1207 | /* Need tasklist lock for parent etc handling! */ | 1216 | /* Need tasklist lock for parent etc handling! */ |
1208 | write_lock_irq(&tasklist_lock); | 1217 | write_lock_irq(&tasklist_lock); |
1209 | 1218 | ||
@@ -1318,9 +1327,10 @@ bad_fork_cleanup_security: | |||
1318 | bad_fork_cleanup_policy: | 1327 | bad_fork_cleanup_policy: |
1319 | #ifdef CONFIG_NUMA | 1328 | #ifdef CONFIG_NUMA |
1320 | mpol_free(p->mempolicy); | 1329 | mpol_free(p->mempolicy); |
1321 | bad_fork_cleanup_cpuset: | 1330 | bad_fork_cleanup_cgroup: |
1322 | #endif | 1331 | #endif |
1323 | cpuset_exit(p); | 1332 | cpuset_exit(p); |
1333 | cgroup_exit(p, cgroup_callbacks_done); | ||
1324 | bad_fork_cleanup_delays_binfmt: | 1334 | bad_fork_cleanup_delays_binfmt: |
1325 | delayacct_tsk_free(p); | 1335 | delayacct_tsk_free(p); |
1326 | if (p->binfmt) | 1336 | if (p->binfmt) |