aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c14
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:
1318bad_fork_cleanup_policy: 1327bad_fork_cleanup_policy:
1319#ifdef CONFIG_NUMA 1328#ifdef CONFIG_NUMA
1320 mpol_free(p->mempolicy); 1329 mpol_free(p->mempolicy);
1321bad_fork_cleanup_cpuset: 1330bad_fork_cleanup_cgroup:
1322#endif 1331#endif
1323 cpuset_exit(p); 1332 cpuset_exit(p);
1333 cgroup_exit(p, cgroup_callbacks_done);
1324bad_fork_cleanup_delays_binfmt: 1334bad_fork_cleanup_delays_binfmt:
1325 delayacct_tsk_free(p); 1335 delayacct_tsk_free(p);
1326 if (p->binfmt) 1336 if (p->binfmt)