Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d41d5a01 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

cgroup: Fix cgroup_subsys::exit callback



Make the ::exit method act like ::attach, it is after all very nearly
the same thing.

The bug had no effect on correctness - fixing it is an optimization for
the scheduler. Also, later perf-cgroups patches rely on it.

Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: default avatarPaul Menage <menage@google.com>
LKML-Reference: <1297160655.13327.92.camel@laptop>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent b00560f2
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -474,7 +474,8 @@ struct cgroup_subsys {
			struct cgroup *old_cgrp, struct task_struct *tsk,
			bool threadgroup);
	void (*fork)(struct cgroup_subsys *ss, struct task_struct *task);
	void (*exit)(struct cgroup_subsys *ss, struct task_struct *task);
	void (*exit)(struct cgroup_subsys *ss, struct cgroup *cgrp,
			struct cgroup *old_cgrp, struct task_struct *task);
	int (*populate)(struct cgroup_subsys *ss,
			struct cgroup *cgrp);
	void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp);
+18 −13
Original line number Diff line number Diff line
@@ -4230,20 +4230,8 @@ void cgroup_post_fork(struct task_struct *child)
 */
void cgroup_exit(struct task_struct *tsk, int run_callbacks)
{
	int i;
	struct css_set *cg;

	if (run_callbacks && need_forkexit_callback) {
		/*
		 * modular subsystems can't use callbacks, so no need to lock
		 * the subsys array
		 */
		for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
			struct cgroup_subsys *ss = subsys[i];
			if (ss->exit)
				ss->exit(ss, tsk);
		}
	}
	int i;

	/*
	 * Unlink from the css_set task list if necessary.
@@ -4261,7 +4249,24 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks)
	task_lock(tsk);
	cg = tsk->cgroups;
	tsk->cgroups = &init_css_set;

	if (run_callbacks && need_forkexit_callback) {
		/*
		 * modular subsystems can't use callbacks, so no need to lock
		 * the subsys array
		 */
		for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
			struct cgroup_subsys *ss = subsys[i];
			if (ss->exit) {
				struct cgroup *old_cgrp =
					rcu_dereference_raw(cg->subsys[i])->cgroup;
				struct cgroup *cgrp = task_cgroup(tsk, i);
				ss->exit(ss, cgrp, old_cgrp, tsk);
			}
		}
	}
	task_unlock(tsk);

	if (cg)
		put_css_set_taskexit(cg);
}
+2 −4
Original line number Diff line number Diff line
@@ -606,9 +606,6 @@ static inline struct task_group *task_group(struct task_struct *p)
	struct task_group *tg;
	struct cgroup_subsys_state *css;

	if (p->flags & PF_EXITING)
		return &root_task_group;

	css = task_subsys_state_check(p, cpu_cgroup_subsys_id,
			lockdep_is_held(&task_rq(p)->lock));
	tg = container_of(css, struct task_group, css);
@@ -8863,7 +8860,8 @@ cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
}

static void
cpu_cgroup_exit(struct cgroup_subsys *ss, struct task_struct *task)
cpu_cgroup_exit(struct cgroup_subsys *ss, struct cgroup *cgrp,
		struct cgroup *old_cgrp, struct task_struct *task)
{
	/*
	 * cgroup_exit() is called in the copy_process() failure path.