summaryrefslogtreecommitdiff
path: root/kernel/cgroup
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cgroup')
-rw-r--r--kernel/cgroup/cgroup.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 16fe1c6cad35..502769b2683c 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -5900,17 +5900,20 @@ static struct cgroup *cgroup_get_from_file(struct file *f)
/**
* cgroup_can_fork - called on a new task before the process is exposed
- * @child: the task in question.
+ * @child: the child process
*
- * This calls the subsystem can_fork() callbacks. If the can_fork() callback
- * returns an error, the fork aborts with that error code. This allows for
- * a cgroup subsystem to conditionally allow or deny new forks.
+ * This calls the subsystem can_fork() callbacks. If the cgroup_can_fork()
+ * callback returns an error, the fork aborts with that error code. This
+ * allows for a cgroup subsystem to conditionally allow or deny new forks.
*/
int cgroup_can_fork(struct task_struct *child)
+ __acquires(&cgroup_threadgroup_rwsem) __releases(&cgroup_threadgroup_rwsem)
{
struct cgroup_subsys *ss;
int i, j, ret;
+ cgroup_threadgroup_change_begin(current);
+
do_each_subsys_mask(ss, i, have_canfork_callback) {
ret = ss->can_fork(child);
if (ret)
@@ -5927,17 +5930,20 @@ out_revert:
ss->cancel_fork(child);
}
+ cgroup_threadgroup_change_end(current);
+
return ret;
}
/**
- * cgroup_cancel_fork - called if a fork failed after cgroup_can_fork()
- * @child: the task in question
- *
- * This calls the cancel_fork() callbacks if a fork failed *after*
- * cgroup_can_fork() succeded.
- */
+ * cgroup_cancel_fork - called if a fork failed after cgroup_can_fork()
+ * @child: the child process
+ *
+ * This calls the cancel_fork() callbacks if a fork failed *after*
+ * cgroup_can_fork() succeded.
+ */
void cgroup_cancel_fork(struct task_struct *child)
+ __releases(&cgroup_threadgroup_rwsem)
{
struct cgroup_subsys *ss;
int i;
@@ -5945,19 +5951,19 @@ void cgroup_cancel_fork(struct task_struct *child)
for_each_subsys(ss, i)
if (ss->cancel_fork)
ss->cancel_fork(child);
+
+ cgroup_threadgroup_change_end(current);
}
/**
- * cgroup_post_fork - called on a new task after adding it to the task list
- * @child: the task in question
- *
- * Adds the task to the list running through its css_set if necessary and
- * call the subsystem fork() callbacks. Has to be after the task is
- * visible on the task list in case we race with the first call to
- * cgroup_task_iter_start() - to guarantee that the new task ends up on its
- * list.
+ * cgroup_post_fork - finalize cgroup setup for the child process
+ * @child: the child process
+ *
+ * Attach the child process to its css_set calling the subsystem fork()
+ * callbacks.
*/
void cgroup_post_fork(struct task_struct *child)
+ __releases(&cgroup_threadgroup_rwsem)
{
struct cgroup_subsys *ss;
struct css_set *cset;
@@ -6003,6 +6009,8 @@ void cgroup_post_fork(struct task_struct *child)
do_each_subsys_mask(ss, i, have_fork_callback) {
ss->fork(child);
} while_each_subsys_mask();
+
+ cgroup_threadgroup_change_end(current);
}
/**