aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 848b42195e5b..7a94ef6b35e2 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -814,7 +814,8 @@ void mem_cgroup_del_lru_list(struct page *page, enum lru_list lru)
814 * removed from global LRU. 814 * removed from global LRU.
815 */ 815 */
816 mz = page_cgroup_zoneinfo(pc); 816 mz = page_cgroup_zoneinfo(pc);
817 MEM_CGROUP_ZSTAT(mz, lru) -= 1; 817 /* huge page split is done under lru_lock. so, we have no races. */
818 MEM_CGROUP_ZSTAT(mz, lru) -= 1 << compound_order(page);
818 if (mem_cgroup_is_root(pc->mem_cgroup)) 819 if (mem_cgroup_is_root(pc->mem_cgroup))
819 return; 820 return;
820 VM_BUG_ON(list_empty(&pc->lru)); 821 VM_BUG_ON(list_empty(&pc->lru));
@@ -865,7 +866,8 @@ void mem_cgroup_add_lru_list(struct page *page, enum lru_list lru)
865 return; 866 return;
866 867
867 mz = page_cgroup_zoneinfo(pc); 868 mz = page_cgroup_zoneinfo(pc);
868 MEM_CGROUP_ZSTAT(mz, lru) += 1; 869 /* huge page split is done under lru_lock. so, we have no races. */
870 MEM_CGROUP_ZSTAT(mz, lru) += 1 << compound_order(page);
869 SetPageCgroupAcctLRU(pc); 871 SetPageCgroupAcctLRU(pc);
870 if (mem_cgroup_is_root(pc->mem_cgroup)) 872 if (mem_cgroup_is_root(pc->mem_cgroup))
871 return; 873 return;
@@ -2152,14 +2154,26 @@ void mem_cgroup_split_huge_fixup(struct page *head, struct page *tail)
2152 unsigned long flags; 2154 unsigned long flags;
2153 2155
2154 /* 2156 /*
2155 * We have no races witch charge/uncharge but will have races with 2157 * We have no races with charge/uncharge but will have races with
2156 * page state accounting. 2158 * page state accounting.
2157 */ 2159 */
2158 move_lock_page_cgroup(head_pc, &flags); 2160 move_lock_page_cgroup(head_pc, &flags);
2159 2161
2160 tail_pc->mem_cgroup = head_pc->mem_cgroup; 2162 tail_pc->mem_cgroup = head_pc->mem_cgroup;
2161 smp_wmb(); /* see __commit_charge() */ 2163 smp_wmb(); /* see __commit_charge() */
2162 /* we don't need to copy all flags...*/ 2164 if (PageCgroupAcctLRU(head_pc)) {
2165 enum lru_list lru;
2166 struct mem_cgroup_per_zone *mz;
2167
2168 /*
2169 * LRU flags cannot be copied because we need to add tail
2170 *.page to LRU by generic call and our hook will be called.
2171 * We hold lru_lock, then, reduce counter directly.
2172 */
2173 lru = page_lru(head);
2174 mz = page_cgroup_zoneinfo(head_pc);
2175 MEM_CGROUP_ZSTAT(mz, lru) -= 1;
2176 }
2163 tail_pc->flags = head_pc->flags & ~PCGF_NOCOPY_AT_SPLIT; 2177 tail_pc->flags = head_pc->flags & ~PCGF_NOCOPY_AT_SPLIT;
2164 move_unlock_page_cgroup(head_pc, &flags); 2178 move_unlock_page_cgroup(head_pc, &flags);
2165} 2179}