aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorPaul Menage <menage@google.com>2007-10-19 02:39:33 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 14:53:36 -0400
commitb4f48b6363c81ca743ef46943ef23fd72e60f679 (patch)
tree40437b78e2d7a7d9d71e7bd63bc96e1ad02daa94 /kernel/fork.c
parent355e0c48b757b7fcc79ccb98fda8105ed37a1598 (diff)
Task Control Groups: add fork()/exit() hooks
This adds the necessary hooks to the fork() and exit() paths to ensure that new children inherit their parent's cgroup assignments, and that exiting processes release reference counts on their cgroups. Signed-off-by: Paul Menage <menage@google.com> Cc: Serge E. Hallyn <serue@us.ibm.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Dave Hansen <haveblue@us.ibm.com> Cc: Balbir Singh <balbir@in.ibm.com> Cc: Paul Jackson <pj@sgi.com> Cc: Kirill Korotaev <dev@openvz.org> Cc: Herbert Poetzl <herbert@13thfloor.at> Cc: Srivatsa Vaddagiri <vatsa@in.ibm.com> Cc: Cedric Le Goater <clg@fr.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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 2ce28f165e3..e7c181454dc 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)