diff options
-rw-r--r-- | mm/memcontrol.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index e7f47a38fe4f..c1f9b79817d7 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -4654,8 +4654,8 @@ static enum mc_target_type get_mctgt_type(struct vm_area_struct *vma, | |||
4654 | 4654 | ||
4655 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 4655 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
4656 | /* | 4656 | /* |
4657 | * We don't consider swapping or file mapped pages because THP does not | 4657 | * We don't consider PMD mapped swapping or file mapped pages because THP does |
4658 | * support them for now. | 4658 | * not support them for now. |
4659 | * Caller should make sure that pmd_trans_huge(pmd) is true. | 4659 | * Caller should make sure that pmd_trans_huge(pmd) is true. |
4660 | */ | 4660 | */ |
4661 | static enum mc_target_type get_mctgt_type_thp(struct vm_area_struct *vma, | 4661 | static enum mc_target_type get_mctgt_type_thp(struct vm_area_struct *vma, |
@@ -5913,6 +5913,7 @@ static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) | |||
5913 | void mem_cgroup_swapout(struct page *page, swp_entry_t entry) | 5913 | void mem_cgroup_swapout(struct page *page, swp_entry_t entry) |
5914 | { | 5914 | { |
5915 | struct mem_cgroup *memcg, *swap_memcg; | 5915 | struct mem_cgroup *memcg, *swap_memcg; |
5916 | unsigned int nr_entries; | ||
5916 | unsigned short oldid; | 5917 | unsigned short oldid; |
5917 | 5918 | ||
5918 | VM_BUG_ON_PAGE(PageLRU(page), page); | 5919 | VM_BUG_ON_PAGE(PageLRU(page), page); |
@@ -5933,19 +5934,24 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) | |||
5933 | * ancestor for the swap instead and transfer the memory+swap charge. | 5934 | * ancestor for the swap instead and transfer the memory+swap charge. |
5934 | */ | 5935 | */ |
5935 | swap_memcg = mem_cgroup_id_get_online(memcg); | 5936 | swap_memcg = mem_cgroup_id_get_online(memcg); |
5936 | oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg), 1); | 5937 | nr_entries = hpage_nr_pages(page); |
5938 | /* Get references for the tail pages, too */ | ||
5939 | if (nr_entries > 1) | ||
5940 | mem_cgroup_id_get_many(swap_memcg, nr_entries - 1); | ||
5941 | oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg), | ||
5942 | nr_entries); | ||
5937 | VM_BUG_ON_PAGE(oldid, page); | 5943 | VM_BUG_ON_PAGE(oldid, page); |
5938 | mem_cgroup_swap_statistics(swap_memcg, 1); | 5944 | mem_cgroup_swap_statistics(swap_memcg, nr_entries); |
5939 | 5945 | ||
5940 | page->mem_cgroup = NULL; | 5946 | page->mem_cgroup = NULL; |
5941 | 5947 | ||
5942 | if (!mem_cgroup_is_root(memcg)) | 5948 | if (!mem_cgroup_is_root(memcg)) |
5943 | page_counter_uncharge(&memcg->memory, 1); | 5949 | page_counter_uncharge(&memcg->memory, nr_entries); |
5944 | 5950 | ||
5945 | if (memcg != swap_memcg) { | 5951 | if (memcg != swap_memcg) { |
5946 | if (!mem_cgroup_is_root(swap_memcg)) | 5952 | if (!mem_cgroup_is_root(swap_memcg)) |
5947 | page_counter_charge(&swap_memcg->memsw, 1); | 5953 | page_counter_charge(&swap_memcg->memsw, nr_entries); |
5948 | page_counter_uncharge(&memcg->memsw, 1); | 5954 | page_counter_uncharge(&memcg->memsw, nr_entries); |
5949 | } | 5955 | } |
5950 | 5956 | ||
5951 | /* | 5957 | /* |
@@ -5955,7 +5961,8 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) | |||
5955 | * only synchronisation we have for udpating the per-CPU variables. | 5961 | * only synchronisation we have for udpating the per-CPU variables. |
5956 | */ | 5962 | */ |
5957 | VM_BUG_ON(!irqs_disabled()); | 5963 | VM_BUG_ON(!irqs_disabled()); |
5958 | mem_cgroup_charge_statistics(memcg, page, false, -1); | 5964 | mem_cgroup_charge_statistics(memcg, page, PageTransHuge(page), |
5965 | -nr_entries); | ||
5959 | memcg_check_events(memcg, page); | 5966 | memcg_check_events(memcg, page); |
5960 | 5967 | ||
5961 | if (!mem_cgroup_is_root(memcg)) | 5968 | if (!mem_cgroup_is_root(memcg)) |