sched, numa, mm: Add memcg support to do_huge_pmd_numa_page()
Subsystems (3)
tip-bot for Johannes Weiner
maintainerCommit-ID: 3eaf14577ceb5c540e33a4eab967160d374b93b1 Gitweb: http://git.kernel.org/tip/3eaf14577ceb5c540e33a4eab967160d374b93b1 Author: Johannes Weiner <[email protected]> AuthorDate: Thu, 25 Oct 2012 12:49:51 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Mon, 29 Oct 2012 12:15:15 +0100
sched, numa, mm: Add memcg support to do_huge_pmd_numa_page()
Add memory control group support to hugepage migration.
Signed-off-by Johannes Weiner <[email protected]>
Tested-by Zhouping Liu <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Andrea Arcangeli <[email protected]>
Cc Rik van Riel <[email protected]>
Cc Thomas Gleixner <[email protected]>
Signed-off-by Ingo Molnar <[email protected]>
--- mm/huge_memory.c | 15 +++++++++++++++ mm/memcontrol.c | 7 +++++-- 2 files changed, 20 insertions(+), 2 deletions(-)
mm/huge_memory.c +15 -0
@@ -742,6 +742,7 @@ void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned int flags, pmd_t entry) {unsigned long haddr = address &HPAGE_PMD_MASK ; +struct mem_cgroup *memcg =NULL ;struct page *new_page =NULL ;struct page *page =NULL ;int node, lru;
@@ -832,6 +833,14 @@ migrate:return ; } +/* +* Traditional migration needs to prepare the memcg charge +* transaction early to prevent the old page from being +* uncharged when installing migration entries. Here we can +* save the potential rollback and start the charge transfer +* only when migration is already known to end successfully. +*/ +mem_cgroup_prepare_migration (page, new_page, &memcg); entry =mk_pmd (new_page, vma->vm_page_prot); entry =maybe_pmd_mkwrite (pmd_mkdirty (entry), vma);
@@ -842,6 +851,12 @@ migrate:set_pmd_at (mm, haddr, pmd, entry);update_mmu_cache_pmd (vma, address, entry);page_remove_rmap (page); +/* +* Finish the charge transaction under the page table lock to +* prevent split_huge_page() from dividing up the charge +* before it's fully transferred to the new page. +*/ +mem_cgroup_end_migration (memcg, page, new_page, true);spin_unlock (&mm->page_table_lock);put_page (page);/* Drop the rmap reference */
mm/memcontrol.c +5 -2
@@ -3255,15 +3255,18 @@ void mem_cgroup_prepare_migration(struct page *page, struct page *newpage, struct mem_cgroup **memcgp) {struct mem_cgroup *memcg =NULL ; +unsigned int nr_pages =1 ;struct page_cgroup *pc;enum charge_type ctype; *memcgp =NULL ; -VM_BUG_ON (PageTransHuge (page));if (mem_cgroup_disabled ())return ; +if (PageTransHuge (page)) + nr_pages <<=compound_order (page); + pc =lookup_page_cgroup (page);lock_page_cgroup (pc);if (PageCgroupUsed (pc)) {
@@ -3325,7 +3328,7 @@ void mem_cgroup_prepare_migration(struct page *page, struct page *newpage,* charged to the res_counter since we plan on replacing the * old one and only one page is going to be left afterwards. */ -__mem_cgroup_commit_charge (memcg, newpage,1 , ctype, false); +__mem_cgroup_commit_charge (memcg, newpage, nr_pages, ctype, false); }/* remove redundant charge if migration failed*/