]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
hugetlb: migrate memcg info from oldpage to new page during migration
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Wed, 25 Apr 2012 01:03:38 +0000 (11:03 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Mon, 30 Apr 2012 05:17:22 +0000 (15:17 +1000)
With HugeTLB pages, memcg is uncharged in compound page destructor.  Since
we are holding a hugepage reference, we can be sure that old page won't
get uncharged till the last put_page().  On successful migrate, we can
move the memcg information to new page's page_cgroup and mark the old
page's page_cgroup unused.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Hillf Danton <dhillf@gmail.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/memcontrol.h
mm/memcontrol.c
mm/migrate.c

index 6a293b85f9b3512e451654d002dc6950a83f21ce..4eb13b349e67844737fa328b55b87cee366bfd5e 100644 (file)
@@ -464,6 +464,8 @@ extern int mem_cgroup_move_hugetlb_parent(int idx, struct cgroup *cgroup,
                                          struct page *page);
 extern bool mem_cgroup_have_hugetlb_usage(struct cgroup *cgroup);
 
+extern void  mem_cgroup_hugetlb_migrate(struct page *oldhpage,
+                                       struct page *newhpage);
 #else
 static inline int
 mem_cgroup_hugetlb_charge_page(int idx, unsigned long nr_pages,
@@ -499,6 +501,12 @@ static inline int mem_cgroup_hugetlb_file_init(int idx)
        return 0;
 }
 
+static inline  void  mem_cgroup_hugetlb_migrate(struct page *oldhpage,
+                                               struct page *newhpage)
+{
+       return;
+}
+
 #endif  /* CONFIG_MEM_RES_CTLR_HUGETLB */
 #endif /* _LINUX_MEMCONTROL_H */
 
index 6331564ac7bd4367fb61e77ceb69a4e19bd4b88a..308c56619bb6cadfef61d56ab248a494c1febf58 100644 (file)
@@ -3374,6 +3374,34 @@ err_out:
 out:
        return ret;
 }
+
+void  mem_cgroup_hugetlb_migrate(struct page *oldhpage, struct page *newhpage)
+{
+       struct mem_cgroup *memcg;
+       struct page_cgroup *pc;
+
+       VM_BUG_ON(!PageHuge(oldhpage));
+
+       if (mem_cgroup_disabled())
+               return;
+
+       pc = lookup_page_cgroup(oldhpage);
+       lock_page_cgroup(pc);
+       memcg = pc->mem_cgroup;
+       pc->mem_cgroup = root_mem_cgroup;
+       ClearPageCgroupUsed(pc);
+       cgroup_exclude_rmdir(&memcg->css);
+       unlock_page_cgroup(pc);
+
+       /* move the mem_cg details to new cgroup */
+       pc = lookup_page_cgroup(newhpage);
+       lock_page_cgroup(pc);
+       pc->mem_cgroup = memcg;
+       SetPageCgroupUsed(pc);
+       unlock_page_cgroup(pc);
+       cgroup_release_and_wakeup_rmdir(&memcg->css);
+       return;
+}
 #endif /* CONFIG_MEM_RES_CTLR_HUGETLB */
 
 /*
index 69065ab09d0815065e4bbadb0a08969cc8374f91..8bf5e1d5a0a3427b3b72f31eded10b30caf8e03b 100644 (file)
@@ -928,6 +928,10 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
 
        if (anon_vma)
                put_anon_vma(anon_vma);
+
+       if (!rc)
+               mem_cgroup_hugetlb_migrate(hpage, new_hpage);
+
        unlock_page(hpage);
 out:
        put_page(new_hpage);