diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2008-02-07 03:14:10 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 11:42:19 -0500 |
commit | ae41be374293e70e1ed441d986afcc6e744ef9d9 (patch) | |
tree | d8e2143820bbf3ed2f1f79ed99ee430284567b93 /include/linux/memcontrol.h | |
parent | 9175e0311ec9e6d1bf1f6dfecf9268baf08765e6 (diff) |
bugfix for memory cgroup controller: migration under memory controller fix
While using memory control cgroup, page-migration under it works as following.
==
1. uncharge all refs at try to unmap.
2. charge regs again remove_migration_ptes()
==
This is simple but has following problems.
==
The page is uncharged and charged back again if *mapped*.
- This means that cgroup before migration can be different from one after
migration
- If page is not mapped but charged as page cache, charge is just ignored
(because not mapped, it will not be uncharged before migration)
This is memory leak.
==
This patch tries to keep memory cgroup at page migration by increasing
one refcnt during it. 3 functions are added.
mem_cgroup_prepare_migration() --- increase refcnt of page->page_cgroup
mem_cgroup_end_migration() --- decrease refcnt of page->page_cgroup
mem_cgroup_page_migration() --- copy page->page_cgroup from old page to
new page.
During migration
- old page is under PG_locked.
- new page is under PG_locked, too.
- both old page and new page is not on LRU.
These 3 facts guarantee that page_cgroup() migration has no race.
Tested and worked well in x86_64/fake-NUMA box.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: Pavel Emelianov <xemul@openvz.org>
Cc: Paul Menage <menage@google.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Kirill Korotaev <dev@sw.ru>
Cc: Herbert Poetzl <herbert@13thfloor.at>
Cc: David Rientjes <rientjes@google.com>
Cc: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/memcontrol.h')
-rw-r--r-- | include/linux/memcontrol.h | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 42536c737d9c..4ec712967f7c 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
@@ -60,6 +60,10 @@ static inline void mem_cgroup_uncharge_page(struct page *page) | |||
60 | mem_cgroup_uncharge(page_get_page_cgroup(page)); | 60 | mem_cgroup_uncharge(page_get_page_cgroup(page)); |
61 | } | 61 | } |
62 | 62 | ||
63 | extern int mem_cgroup_prepare_migration(struct page *page); | ||
64 | extern void mem_cgroup_end_migration(struct page *page); | ||
65 | extern void mem_cgroup_page_migration(struct page *page, struct page *newpage); | ||
66 | |||
63 | #else /* CONFIG_CGROUP_MEM_CONT */ | 67 | #else /* CONFIG_CGROUP_MEM_CONT */ |
64 | static inline void mm_init_cgroup(struct mm_struct *mm, | 68 | static inline void mm_init_cgroup(struct mm_struct *mm, |
65 | struct task_struct *p) | 69 | struct task_struct *p) |
@@ -117,6 +121,21 @@ static inline int task_in_mem_cgroup(struct task_struct *task, | |||
117 | return 1; | 121 | return 1; |
118 | } | 122 | } |
119 | 123 | ||
124 | static inline int mem_cgroup_prepare_migration(struct page *page) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static inline void mem_cgroup_end_migration(struct page *page) | ||
130 | { | ||
131 | } | ||
132 | |||
133 | static inline void | ||
134 | mem_cgroup_page_migration(struct page *page, struct page *newpage) | ||
135 | { | ||
136 | } | ||
137 | |||
138 | |||
120 | #endif /* CONFIG_CGROUP_MEM_CONT */ | 139 | #endif /* CONFIG_CGROUP_MEM_CONT */ |
121 | 140 | ||
122 | #endif /* _LINUX_MEMCONTROL_H */ | 141 | #endif /* _LINUX_MEMCONTROL_H */ |