diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2008-07-25 04:47:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-25 13:53:37 -0400 |
commit | e8589cc189f96b87348ae83ea4db38eaac624135 (patch) | |
tree | 6693422dc81e6da78c4ad892b0d326fb7f946dda /include/linux | |
parent | 508b7be0a5b06b64203512ed9b34191cddc83f56 (diff) |
memcg: better migration handling
This patch changes page migration under memory controller to use a
different algorithm. (thanks to Christoph for new idea.)
Before:
- page_cgroup is migrated from an old page to a new page.
After:
- a new page is accounted , no reuse of page_cgroup.
Pros:
- We can avoid compliated lock depndencies and races in migration.
Cons:
- new param to mem_cgroup_charge_common().
- mem_cgroup_getref() is added for handling ref_cnt ping-pong.
This version simplifies complicated lock dependency in page migraiton
under memory resource controller.
new refcnt sequence is following.
a mapped page:
prepage_migration() ..... +1 to NEW page
try_to_unmap() ..... all refs to OLD page is gone.
move_pages() ..... +1 to NEW page if page cache.
remap... ..... all refs from *map* is added to NEW one.
end_migration() ..... -1 to New page.
page's mapcount + (page_is_cache) refs are added to NEW one.
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Pavel Emelyanov <xemul@openvz.org>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: YAMAMOTO Takashi <yamamoto@valinux.co.jp>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
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/memcontrol.h | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index e6608776bc96..84ead2aa6f18 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
@@ -50,9 +50,10 @@ extern struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p); | |||
50 | #define mm_match_cgroup(mm, cgroup) \ | 50 | #define mm_match_cgroup(mm, cgroup) \ |
51 | ((cgroup) == mem_cgroup_from_task((mm)->owner)) | 51 | ((cgroup) == mem_cgroup_from_task((mm)->owner)) |
52 | 52 | ||
53 | extern int mem_cgroup_prepare_migration(struct page *page); | 53 | extern int |
54 | mem_cgroup_prepare_migration(struct page *page, struct page *newpage); | ||
54 | extern void mem_cgroup_end_migration(struct page *page); | 55 | extern void mem_cgroup_end_migration(struct page *page); |
55 | extern void mem_cgroup_page_migration(struct page *page, struct page *newpage); | 56 | extern int mem_cgroup_getref(struct page *page); |
56 | 57 | ||
57 | /* | 58 | /* |
58 | * For memory reclaim. | 59 | * For memory reclaim. |
@@ -112,7 +113,8 @@ static inline int task_in_mem_cgroup(struct task_struct *task, | |||
112 | return 1; | 113 | return 1; |
113 | } | 114 | } |
114 | 115 | ||
115 | static inline int mem_cgroup_prepare_migration(struct page *page) | 116 | static inline int |
117 | mem_cgroup_prepare_migration(struct page *page, struct page *newpage) | ||
116 | { | 118 | { |
117 | return 0; | 119 | return 0; |
118 | } | 120 | } |
@@ -121,8 +123,7 @@ static inline void mem_cgroup_end_migration(struct page *page) | |||
121 | { | 123 | { |
122 | } | 124 | } |
123 | 125 | ||
124 | static inline void | 126 | static inline void mem_cgroup_getref(struct page *page) |
125 | mem_cgroup_page_migration(struct page *page, struct page *newpage) | ||
126 | { | 127 | { |
127 | } | 128 | } |
128 | 129 | ||