forked from Minki/linux
memrlimit: cgroup mm owner callback changes to add task info
This patch adds an additional field to the mm_owner callbacks. This field is required to get to the mm that changed. Hold mmap_sem in write mode before calling the mm_owner_changed callback [hugh@veritas.com: fix mmap_sem deadlock] Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com> Cc: Sudhir Kumar <skumar@linux.vnet.ibm.com> Cc: YAMAMOTO Takashi <yamamoto@valinux.co.jp> Cc: Paul Menage <menage@google.com> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Pavel Emelianov <xemul@openvz.org> Cc: Balbir Singh <balbir@linux.vnet.ibm.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: David Rientjes <rientjes@google.com> Cc: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
1648993fb0
commit
9363b9f23c
@ -326,7 +326,8 @@ struct cgroup_subsys {
|
|||||||
*/
|
*/
|
||||||
void (*mm_owner_changed)(struct cgroup_subsys *ss,
|
void (*mm_owner_changed)(struct cgroup_subsys *ss,
|
||||||
struct cgroup *old,
|
struct cgroup *old,
|
||||||
struct cgroup *new);
|
struct cgroup *new,
|
||||||
|
struct task_struct *p);
|
||||||
int subsys_id;
|
int subsys_id;
|
||||||
int active;
|
int active;
|
||||||
int disabled;
|
int disabled;
|
||||||
|
@ -2735,6 +2735,8 @@ void cgroup_fork_callbacks(struct task_struct *child)
|
|||||||
* Called on every change to mm->owner. mm_init_owner() does not
|
* Called on every change to mm->owner. mm_init_owner() does not
|
||||||
* invoke this routine, since it assigns the mm->owner the first time
|
* invoke this routine, since it assigns the mm->owner the first time
|
||||||
* and does not change it.
|
* 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)
|
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)
|
if (oldcgrp == newcgrp)
|
||||||
continue;
|
continue;
|
||||||
if (ss->mm_owner_changed)
|
if (ss->mm_owner_changed)
|
||||||
ss->mm_owner_changed(ss, oldcgrp, newcgrp);
|
ss->mm_owner_changed(ss, oldcgrp, newcgrp, new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -640,24 +640,23 @@ retry:
|
|||||||
assign_new_owner:
|
assign_new_owner:
|
||||||
BUG_ON(c == p);
|
BUG_ON(c == p);
|
||||||
get_task_struct(c);
|
get_task_struct(c);
|
||||||
|
read_unlock(&tasklist_lock);
|
||||||
|
down_write(&mm->mmap_sem);
|
||||||
/*
|
/*
|
||||||
* The task_lock protects c->mm from changing.
|
* The task_lock protects c->mm from changing.
|
||||||
* We always want mm->owner->mm == mm
|
* We always want mm->owner->mm == mm
|
||||||
*/
|
*/
|
||||||
task_lock(c);
|
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) {
|
if (c->mm != mm) {
|
||||||
task_unlock(c);
|
task_unlock(c);
|
||||||
|
up_write(&mm->mmap_sem);
|
||||||
put_task_struct(c);
|
put_task_struct(c);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
cgroup_mm_owner_callbacks(mm->owner, c);
|
cgroup_mm_owner_callbacks(mm->owner, c);
|
||||||
mm->owner = c;
|
mm->owner = c;
|
||||||
task_unlock(c);
|
task_unlock(c);
|
||||||
|
up_write(&mm->mmap_sem);
|
||||||
put_task_struct(c);
|
put_task_struct(c);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_MM_OWNER */
|
#endif /* CONFIG_MM_OWNER */
|
||||||
|
Loading…
Reference in New Issue
Block a user