@@ -4654,8 +4654,8 @@ static enum mc_target_type get_mctgt_type(struct vm_area_struct *vma,
4654
4654
4655
4655
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
4656
4656
/*
4657
- * We don't consider swapping or file mapped pages because THP does not
4658
- * support them for now.
4657
+ * We don't consider PMD mapped swapping or file mapped pages because THP does
4658
+ * not support them for now.
4659
4659
* Caller should make sure that pmd_trans_huge(pmd) is true.
4660
4660
*/
4661
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
5913
void mem_cgroup_swapout (struct page * page , swp_entry_t entry )
5914
5914
{
5915
5915
struct mem_cgroup * memcg , * swap_memcg ;
5916
+ unsigned int nr_entries ;
5916
5917
unsigned short oldid ;
5917
5918
5918
5919
VM_BUG_ON_PAGE (PageLRU (page ), page );
@@ -5933,19 +5934,24 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
5933
5934
* ancestor for the swap instead and transfer the memory+swap charge.
5934
5935
*/
5935
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
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
5946
page -> mem_cgroup = NULL ;
5941
5947
5942
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
5951
if (memcg != swap_memcg ) {
5946
5952
if (!mem_cgroup_is_root (swap_memcg ))
5947
- page_counter_charge (& swap_memcg -> memsw , 1 );
5948
- page_counter_uncharge (& memcg -> memsw , 1 );
5953
+ page_counter_charge (& swap_memcg -> memsw , nr_entries );
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
5961
* only synchronisation we have for udpating the per-CPU variables.
5956
5962
*/
5957
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
5966
memcg_check_events (memcg , page );
5960
5967
5961
5968
if (!mem_cgroup_is_root (memcg ))
0 commit comments