From f260492c9569a0ba66420fcb4db6074d849933ad Mon Sep 17 00:00:00 2001 From: Balbir Singh Date: Wed, 15 Oct 2008 22:01:05 -0700 Subject: [PATCH] --- yaml --- r: 114685 b: refs/heads/master c: 9363b9f23c9cc36cc8ef6c05fdf879ee4a96ae92 h: refs/heads/master i: 114683: 1b8e6b599055e25138a35e75962dcdfc0008b44a v: v3 --- [refs] | 2 +- trunk/include/linux/cgroup.h | 3 ++- trunk/kernel/cgroup.c | 4 +++- trunk/kernel/exit.c | 9 ++++----- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index 4a62dd1bdccd..b243b3644e1e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1648993fb05c487947c1cec6307aca29d8002abe +refs/heads/master: 9363b9f23c9cc36cc8ef6c05fdf879ee4a96ae92 diff --git a/trunk/include/linux/cgroup.h b/trunk/include/linux/cgroup.h index c98dd7cb7076..30934e4bfaab 100644 --- a/trunk/include/linux/cgroup.h +++ b/trunk/include/linux/cgroup.h @@ -326,7 +326,8 @@ struct cgroup_subsys { */ void (*mm_owner_changed)(struct cgroup_subsys *ss, struct cgroup *old, - struct cgroup *new); + struct cgroup *new, + struct task_struct *p); int subsys_id; int active; int disabled; diff --git a/trunk/kernel/cgroup.c b/trunk/kernel/cgroup.c index a0123d75ec9a..8c6e1c17e6d3 100644 --- a/trunk/kernel/cgroup.c +++ b/trunk/kernel/cgroup.c @@ -2735,6 +2735,8 @@ void cgroup_fork_callbacks(struct task_struct *child) * Called on every change to mm->owner. mm_init_owner() does not * invoke this routine, since it assigns the mm->owner the first time * and does not change it. + * + * The callbacks are invoked with mmap_sem held in read mode. */ void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new) { @@ -2750,7 +2752,7 @@ void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new) if (oldcgrp == newcgrp) continue; if (ss->mm_owner_changed) - ss->mm_owner_changed(ss, oldcgrp, newcgrp); + ss->mm_owner_changed(ss, oldcgrp, newcgrp, new); } } } diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 85a83c831856..0ef4673e351b 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -640,24 +640,23 @@ void mm_update_next_owner(struct mm_struct *mm) assign_new_owner: BUG_ON(c == p); get_task_struct(c); + read_unlock(&tasklist_lock); + down_write(&mm->mmap_sem); /* * The task_lock protects c->mm from changing. * We always want mm->owner->mm == mm */ task_lock(c); - /* - * Delay read_unlock() till we have the task_lock() - * to ensure that c does not slip away underneath us - */ - read_unlock(&tasklist_lock); if (c->mm != mm) { task_unlock(c); + up_write(&mm->mmap_sem); put_task_struct(c); goto retry; } cgroup_mm_owner_callbacks(mm->owner, c); mm->owner = c; task_unlock(c); + up_write(&mm->mmap_sem); put_task_struct(c); } #endif /* CONFIG_MM_OWNER */