Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hugetlb/cgroup: migrate hugetlb cgroup info from oldpage to new page during migration

With HugeTLB pages, hugetlb cgroup 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().

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Cc: David Rientjes <rientjes@google.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Hillf Danton <dhillf@gmail.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Aneesh Kumar K.V and committed by
Linus Torvalds
8e6ac7fa abb8206c

+33
+8
include/linux/hugetlb_cgroup.h
··· 63 63 extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, 64 64 struct hugetlb_cgroup *h_cg); 65 65 extern int hugetlb_cgroup_file_init(int idx) __init; 66 + extern void hugetlb_cgroup_migrate(struct page *oldhpage, 67 + struct page *newhpage); 66 68 67 69 #else 68 70 static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page) ··· 114 112 static inline int __init hugetlb_cgroup_file_init(int idx) 115 113 { 116 114 return 0; 115 + } 116 + 117 + static inline void hugetlb_cgroup_migrate(struct page *oldhpage, 118 + struct page *newhpage) 119 + { 120 + return; 117 121 } 118 122 119 123 #endif /* CONFIG_MEM_RES_CTLR_HUGETLB */
+20
mm/hugetlb_cgroup.c
··· 386 386 return 0; 387 387 } 388 388 389 + void hugetlb_cgroup_migrate(struct page *oldhpage, struct page *newhpage) 390 + { 391 + struct hugetlb_cgroup *h_cg; 392 + 393 + if (hugetlb_cgroup_disabled()) 394 + return; 395 + 396 + VM_BUG_ON(!PageHuge(oldhpage)); 397 + spin_lock(&hugetlb_lock); 398 + h_cg = hugetlb_cgroup_from_page(oldhpage); 399 + set_hugetlb_cgroup(oldhpage, NULL); 400 + cgroup_exclude_rmdir(&h_cg->css); 401 + 402 + /* move the h_cg details to new cgroup */ 403 + set_hugetlb_cgroup(newhpage, h_cg); 404 + spin_unlock(&hugetlb_lock); 405 + cgroup_release_and_wakeup_rmdir(&h_cg->css); 406 + return; 407 + } 408 + 389 409 struct cgroup_subsys hugetlb_subsys = { 390 410 .name = "hugetlb", 391 411 .create = hugetlb_cgroup_create,
+5
mm/migrate.c
··· 33 33 #include <linux/memcontrol.h> 34 34 #include <linux/syscalls.h> 35 35 #include <linux/hugetlb.h> 36 + #include <linux/hugetlb_cgroup.h> 36 37 #include <linux/gfp.h> 37 38 38 39 #include <asm/tlbflush.h> ··· 932 931 933 932 if (anon_vma) 934 933 put_anon_vma(anon_vma); 934 + 935 + if (!rc) 936 + hugetlb_cgroup_migrate(hpage, new_hpage); 937 + 935 938 unlock_page(hpage); 936 939 out: 937 940 put_page(new_hpage);