Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os 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>

authored by

Balbir Singh and committed by
Linus Torvalds
9363b9f2 1648993f

+9 -7
+2 -1
include/linux/cgroup.h
··· 326 326 */ 327 327 void (*mm_owner_changed)(struct cgroup_subsys *ss, 328 328 struct cgroup *old, 329 - struct cgroup *new); 329 + struct cgroup *new, 330 + struct task_struct *p); 330 331 int subsys_id; 331 332 int active; 332 333 int disabled;
+3 -1
kernel/cgroup.c
··· 2735 2735 * Called on every change to mm->owner. mm_init_owner() does not 2736 2736 * invoke this routine, since it assigns the mm->owner the first time 2737 2737 * and does not change it. 2738 + * 2739 + * The callbacks are invoked with mmap_sem held in read mode. 2738 2740 */ 2739 2741 void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new) 2740 2742 { ··· 2752 2750 if (oldcgrp == newcgrp) 2753 2751 continue; 2754 2752 if (ss->mm_owner_changed) 2755 - ss->mm_owner_changed(ss, oldcgrp, newcgrp); 2753 + ss->mm_owner_changed(ss, oldcgrp, newcgrp, new); 2756 2754 } 2757 2755 } 2758 2756 }
+4 -5
kernel/exit.c
··· 640 640 assign_new_owner: 641 641 BUG_ON(c == p); 642 642 get_task_struct(c); 643 + read_unlock(&tasklist_lock); 644 + down_write(&mm->mmap_sem); 643 645 /* 644 646 * The task_lock protects c->mm from changing. 645 647 * We always want mm->owner->mm == mm 646 648 */ 647 649 task_lock(c); 648 - /* 649 - * Delay read_unlock() till we have the task_lock() 650 - * to ensure that c does not slip away underneath us 651 - */ 652 - read_unlock(&tasklist_lock); 653 650 if (c->mm != mm) { 654 651 task_unlock(c); 652 + up_write(&mm->mmap_sem); 655 653 put_task_struct(c); 656 654 goto retry; 657 655 } 658 656 cgroup_mm_owner_callbacks(mm->owner, c); 659 657 mm->owner = c; 660 658 task_unlock(c); 659 + up_write(&mm->mmap_sem); 661 660 put_task_struct(c); 662 661 } 663 662 #endif /* CONFIG_MM_OWNER */