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>
This commit is contained in:
		
					parent
					
						
							
								abb8206cb0
							
						
					
				
			
			
				commit
				
					
						8e6ac7fab3
					
				
			
		
					 3 changed files with 33 additions and 0 deletions
				
			
		| 
						 | 
					@ -63,6 +63,8 @@ extern void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
 | 
				
			||||||
extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages,
 | 
					extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages,
 | 
				
			||||||
					   struct hugetlb_cgroup *h_cg);
 | 
										   struct hugetlb_cgroup *h_cg);
 | 
				
			||||||
extern int hugetlb_cgroup_file_init(int idx) __init;
 | 
					extern int hugetlb_cgroup_file_init(int idx) __init;
 | 
				
			||||||
 | 
					extern void hugetlb_cgroup_migrate(struct page *oldhpage,
 | 
				
			||||||
 | 
									   struct page *newhpage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
 | 
					static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
 | 
				
			||||||
| 
						 | 
					@ -114,5 +116,11 @@ static inline int __init hugetlb_cgroup_file_init(int idx)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void hugetlb_cgroup_migrate(struct page *oldhpage,
 | 
				
			||||||
 | 
										  struct page *newhpage)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  /* CONFIG_MEM_RES_CTLR_HUGETLB */
 | 
					#endif  /* CONFIG_MEM_RES_CTLR_HUGETLB */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -386,6 +386,26 @@ int __init hugetlb_cgroup_file_init(int idx)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hugetlb_cgroup_migrate(struct page *oldhpage, struct page *newhpage)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct hugetlb_cgroup *h_cg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (hugetlb_cgroup_disabled())
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						VM_BUG_ON(!PageHuge(oldhpage));
 | 
				
			||||||
 | 
						spin_lock(&hugetlb_lock);
 | 
				
			||||||
 | 
						h_cg = hugetlb_cgroup_from_page(oldhpage);
 | 
				
			||||||
 | 
						set_hugetlb_cgroup(oldhpage, NULL);
 | 
				
			||||||
 | 
						cgroup_exclude_rmdir(&h_cg->css);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* move the h_cg details to new cgroup */
 | 
				
			||||||
 | 
						set_hugetlb_cgroup(newhpage, h_cg);
 | 
				
			||||||
 | 
						spin_unlock(&hugetlb_lock);
 | 
				
			||||||
 | 
						cgroup_release_and_wakeup_rmdir(&h_cg->css);
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct cgroup_subsys hugetlb_subsys = {
 | 
					struct cgroup_subsys hugetlb_subsys = {
 | 
				
			||||||
	.name = "hugetlb",
 | 
						.name = "hugetlb",
 | 
				
			||||||
	.create     = hugetlb_cgroup_create,
 | 
						.create     = hugetlb_cgroup_create,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,7 @@
 | 
				
			||||||
#include <linux/memcontrol.h>
 | 
					#include <linux/memcontrol.h>
 | 
				
			||||||
#include <linux/syscalls.h>
 | 
					#include <linux/syscalls.h>
 | 
				
			||||||
#include <linux/hugetlb.h>
 | 
					#include <linux/hugetlb.h>
 | 
				
			||||||
 | 
					#include <linux/hugetlb_cgroup.h>
 | 
				
			||||||
#include <linux/gfp.h>
 | 
					#include <linux/gfp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/tlbflush.h>
 | 
					#include <asm/tlbflush.h>
 | 
				
			||||||
| 
						 | 
					@ -931,6 +932,10 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (anon_vma)
 | 
						if (anon_vma)
 | 
				
			||||||
		put_anon_vma(anon_vma);
 | 
							put_anon_vma(anon_vma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!rc)
 | 
				
			||||||
 | 
							hugetlb_cgroup_migrate(hpage, new_hpage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unlock_page(hpage);
 | 
						unlock_page(hpage);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	put_page(new_hpage);
 | 
						put_page(new_hpage);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue