diff options
-rw-r--r-- | include/linux/hugetlb_cgroup.h | 8 | ||||
-rw-r--r-- | mm/hugetlb_cgroup.c | 20 | ||||
-rw-r--r-- | mm/migrate.c | 5 |
3 files changed, 33 insertions, 0 deletions
diff --git a/include/linux/hugetlb_cgroup.h b/include/linux/hugetlb_cgroup.h index 73f1e600fc12..d73878c694b3 100644 --- a/include/linux/hugetlb_cgroup.h +++ b/include/linux/hugetlb_cgroup.h | |||
@@ -63,6 +63,8 @@ extern void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages, | |||
63 | extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, | 63 | extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, |
64 | struct hugetlb_cgroup *h_cg); | 64 | struct hugetlb_cgroup *h_cg); |
65 | extern int hugetlb_cgroup_file_init(int idx) __init; | 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 | #else | 69 | #else |
68 | static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page) | 70 | 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) | |||
114 | return 0; | 116 | return 0; |
115 | } | 117 | } |
116 | 118 | ||
119 | static inline void hugetlb_cgroup_migrate(struct page *oldhpage, | ||
120 | struct page *newhpage) | ||
121 | { | ||
122 | return; | ||
123 | } | ||
124 | |||
117 | #endif /* CONFIG_MEM_RES_CTLR_HUGETLB */ | 125 | #endif /* CONFIG_MEM_RES_CTLR_HUGETLB */ |
118 | #endif | 126 | #endif |
diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c index d1ca1196e62f..680e4819e077 100644 --- a/mm/hugetlb_cgroup.c +++ b/mm/hugetlb_cgroup.c | |||
@@ -386,6 +386,26 @@ int __init hugetlb_cgroup_file_init(int idx) | |||
386 | return 0; | 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 | struct cgroup_subsys hugetlb_subsys = { | 409 | struct cgroup_subsys hugetlb_subsys = { |
390 | .name = "hugetlb", | 410 | .name = "hugetlb", |
391 | .create = hugetlb_cgroup_create, | 411 | .create = hugetlb_cgroup_create, |
diff --git a/mm/migrate.c b/mm/migrate.c index fdce3a29fc4c..6c37c51565e5 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/memcontrol.h> | 33 | #include <linux/memcontrol.h> |
34 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
35 | #include <linux/hugetlb.h> | 35 | #include <linux/hugetlb.h> |
36 | #include <linux/hugetlb_cgroup.h> | ||
36 | #include <linux/gfp.h> | 37 | #include <linux/gfp.h> |
37 | 38 | ||
38 | #include <asm/tlbflush.h> | 39 | #include <asm/tlbflush.h> |
@@ -931,6 +932,10 @@ static int unmap_and_move_huge_page(new_page_t get_new_page, | |||
931 | 932 | ||
932 | if (anon_vma) | 933 | if (anon_vma) |
933 | put_anon_vma(anon_vma); | 934 | put_anon_vma(anon_vma); |
935 | |||
936 | if (!rc) | ||
937 | hugetlb_cgroup_migrate(hpage, new_hpage); | ||
938 | |||
934 | unlock_page(hpage); | 939 | unlock_page(hpage); |
935 | out: | 940 | out: |
936 | put_page(new_hpage); | 941 | put_page(new_hpage); |