aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorBalbir Singh <balbir@linux.vnet.ibm.com>2008-04-29 04:00:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:10 -0400
commitcf475ad28ac35cc9ba612d67158f29b73b38b05d (patch)
tree2c7cd568d00357bd42643ea602884e731cc24f26 /include/linux
parent29486df325e1fe6e1764afcb19e3370804c2b002 (diff)
cgroups: add an owner to the mm_struct
Remove the mem_cgroup member from mm_struct and instead adds an owner. This approach was suggested by Paul Menage. The advantage of this approach is that, once the mm->owner is known, using the subsystem id, the cgroup can be determined. It also allows several control groups that are virtually grouped by mm_struct, to exist independent of the memory controller i.e., without adding mem_cgroup's for each controller, to mm_struct. A new config option CONFIG_MM_OWNER is added and the memory resource controller selects this config option. This patch also adds cgroup callbacks to notify subsystems when mm->owner changes. The mm_cgroup_changed callback is called with the task_lock() of the new task held and is called just prior to changing the mm->owner. I am indebted to Paul Menage for the several reviews of this patchset and helping me make it lighter and simpler. This patch was tested on a powerpc box, it was compiled with both the MM_OWNER config turned on and off. After the thread group leader exits, it's moved to init_css_state by cgroup_exit(), thus all future charges from runnings threads would be redirected to the init_css_set's subsystem. Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com> Cc: Pavel Emelianov <xemul@openvz.org> Cc: Hugh Dickins <hugh@veritas.com> Cc: Sudhir Kumar <skumar@linux.vnet.ibm.com> Cc: YAMAMOTO Takashi <yamamoto@valinux.co.jp> Cc: Hirokazu Takahashi <taka@valinux.co.jp> Cc: David Rientjes <rientjes@google.com>, Cc: Balbir Singh <balbir@linux.vnet.ibm.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Acked-by: Pekka Enberg <penberg@cs.helsinki.fi> Reviewed-by: Paul Menage <menage@google.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/cgroup.h15
-rw-r--r--include/linux/memcontrol.h16
-rw-r--r--include/linux/mm_types.h5
-rw-r--r--include/linux/sched.h13
4 files changed, 34 insertions, 15 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 095248082b7e..e155aa78d859 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -305,6 +305,12 @@ struct cgroup_subsys {
305 struct cgroup *cgrp); 305 struct cgroup *cgrp);
306 void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp); 306 void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp);
307 void (*bind)(struct cgroup_subsys *ss, struct cgroup *root); 307 void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
308 /*
309 * This routine is called with the task_lock of mm->owner held
310 */
311 void (*mm_owner_changed)(struct cgroup_subsys *ss,
312 struct cgroup *old,
313 struct cgroup *new);
308 int subsys_id; 314 int subsys_id;
309 int active; 315 int active;
310 int disabled; 316 int disabled;
@@ -390,4 +396,13 @@ static inline int cgroupstats_build(struct cgroupstats *stats,
390 396
391#endif /* !CONFIG_CGROUPS */ 397#endif /* !CONFIG_CGROUPS */
392 398
399#ifdef CONFIG_MM_OWNER
400extern void
401cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new);
402#else /* !CONFIG_MM_OWNER */
403static inline void
404cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new)
405{
406}
407#endif /* CONFIG_MM_OWNER */
393#endif /* _LINUX_CGROUP_H */ 408#endif /* _LINUX_CGROUP_H */
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 8b1c4295848b..e6608776bc96 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -27,9 +27,6 @@ struct mm_struct;
27 27
28#ifdef CONFIG_CGROUP_MEM_RES_CTLR 28#ifdef CONFIG_CGROUP_MEM_RES_CTLR
29 29
30extern void mm_init_cgroup(struct mm_struct *mm, struct task_struct *p);
31extern void mm_free_cgroup(struct mm_struct *mm);
32
33#define page_reset_bad_cgroup(page) ((page)->page_cgroup = 0) 30#define page_reset_bad_cgroup(page) ((page)->page_cgroup = 0)
34 31
35extern struct page_cgroup *page_get_page_cgroup(struct page *page); 32extern struct page_cgroup *page_get_page_cgroup(struct page *page);
@@ -48,8 +45,10 @@ extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
48extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask); 45extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask);
49int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem); 46int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem);
50 47
48extern struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p);
49
51#define mm_match_cgroup(mm, cgroup) \ 50#define mm_match_cgroup(mm, cgroup) \
52 ((cgroup) == rcu_dereference((mm)->mem_cgroup)) 51 ((cgroup) == mem_cgroup_from_task((mm)->owner))
53 52
54extern int mem_cgroup_prepare_migration(struct page *page); 53extern int mem_cgroup_prepare_migration(struct page *page);
55extern void mem_cgroup_end_migration(struct page *page); 54extern void mem_cgroup_end_migration(struct page *page);
@@ -73,15 +72,6 @@ extern long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem,
73 struct zone *zone, int priority); 72 struct zone *zone, int priority);
74 73
75#else /* CONFIG_CGROUP_MEM_RES_CTLR */ 74#else /* CONFIG_CGROUP_MEM_RES_CTLR */
76static inline void mm_init_cgroup(struct mm_struct *mm,
77 struct task_struct *p)
78{
79}
80
81static inline void mm_free_cgroup(struct mm_struct *mm)
82{
83}
84
85static inline void page_reset_bad_cgroup(struct page *page) 75static inline void page_reset_bad_cgroup(struct page *page)
86{ 76{
87} 77}
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index e2bae8dde35a..bc97bd54f606 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -225,8 +225,9 @@ struct mm_struct {
225 /* aio bits */ 225 /* aio bits */
226 rwlock_t ioctx_list_lock; /* aio lock */ 226 rwlock_t ioctx_list_lock; /* aio lock */
227 struct kioctx *ioctx_list; 227 struct kioctx *ioctx_list;
228#ifdef CONFIG_CGROUP_MEM_RES_CTLR 228#ifdef CONFIG_MM_OWNER
229 struct mem_cgroup *mem_cgroup; 229 struct task_struct *owner; /* The thread group leader that */
230 /* owns the mm_struct. */
230#endif 231#endif
231}; 232};
232 233
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 024d72b47a0c..1d02babdb2c7 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2148,6 +2148,19 @@ static inline void migration_init(void)
2148#define TASK_SIZE_OF(tsk) TASK_SIZE 2148#define TASK_SIZE_OF(tsk) TASK_SIZE
2149#endif 2149#endif
2150 2150
2151#ifdef CONFIG_MM_OWNER
2152extern void mm_update_next_owner(struct mm_struct *mm);
2153extern void mm_init_owner(struct mm_struct *mm, struct task_struct *p);
2154#else
2155static inline void mm_update_next_owner(struct mm_struct *mm)
2156{
2157}
2158
2159static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
2160{
2161}
2162#endif /* CONFIG_MM_OWNER */
2163
2151#endif /* __KERNEL__ */ 2164#endif /* __KERNEL__ */
2152 2165
2153#endif 2166#endif