aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/cgroups/memory.txt1
-rw-r--r--fs/buffer.c34
-rw-r--r--fs/xfs/xfs_aops.c12
-rw-r--r--include/linux/memcontrol.h1
-rw-r--r--include/linux/mm.h6
-rw-r--r--include/linux/pagemap.h3
-rw-r--r--mm/filemap.c31
-rw-r--r--mm/memcontrol.c24
-rw-r--r--mm/page-writeback.c50
-rw-r--r--mm/rmap.c2
-rw-r--r--mm/truncate.c14
-rw-r--r--mm/vmscan.c17
12 files changed, 156 insertions, 39 deletions
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index f456b4315e86..ff71e16cc752 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -493,6 +493,7 @@ pgpgin - # of charging events to the memory cgroup. The charging
493pgpgout - # of uncharging events to the memory cgroup. The uncharging 493pgpgout - # of uncharging events to the memory cgroup. The uncharging
494 event happens each time a page is unaccounted from the cgroup. 494 event happens each time a page is unaccounted from the cgroup.
495swap - # of bytes of swap usage 495swap - # of bytes of swap usage
496dirty - # of bytes that are waiting to get written back to the disk.
496writeback - # of bytes of file/anon cache that are queued for syncing to 497writeback - # of bytes of file/anon cache that are queued for syncing to
497 disk. 498 disk.
498inactive_anon - # of bytes of anonymous and swap cache memory on inactive 499inactive_anon - # of bytes of anonymous and swap cache memory on inactive
diff --git a/fs/buffer.c b/fs/buffer.c
index f21327d1f673..23b640d5d6e9 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -623,21 +623,22 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode);
623 * 623 *
624 * If warn is true, then emit a warning if the page is not uptodate and has 624 * If warn is true, then emit a warning if the page is not uptodate and has
625 * not been truncated. 625 * not been truncated.
626 *
627 * The caller must hold mem_cgroup_begin_page_stat() lock.
626 */ 628 */
627static void __set_page_dirty(struct page *page, 629static void __set_page_dirty(struct page *page, struct address_space *mapping,
628 struct address_space *mapping, int warn) 630 struct mem_cgroup *memcg, int warn)
629{ 631{
630 unsigned long flags; 632 unsigned long flags;
631 633
632 spin_lock_irqsave(&mapping->tree_lock, flags); 634 spin_lock_irqsave(&mapping->tree_lock, flags);
633 if (page->mapping) { /* Race with truncate? */ 635 if (page->mapping) { /* Race with truncate? */
634 WARN_ON_ONCE(warn && !PageUptodate(page)); 636 WARN_ON_ONCE(warn && !PageUptodate(page));
635 account_page_dirtied(page, mapping); 637 account_page_dirtied(page, mapping, memcg);
636 radix_tree_tag_set(&mapping->page_tree, 638 radix_tree_tag_set(&mapping->page_tree,
637 page_index(page), PAGECACHE_TAG_DIRTY); 639 page_index(page), PAGECACHE_TAG_DIRTY);
638 } 640 }
639 spin_unlock_irqrestore(&mapping->tree_lock, flags); 641 spin_unlock_irqrestore(&mapping->tree_lock, flags);
640 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
641} 642}
642 643
643/* 644/*
@@ -668,6 +669,7 @@ static void __set_page_dirty(struct page *page,
668int __set_page_dirty_buffers(struct page *page) 669int __set_page_dirty_buffers(struct page *page)
669{ 670{
670 int newly_dirty; 671 int newly_dirty;
672 struct mem_cgroup *memcg;
671 struct address_space *mapping = page_mapping(page); 673 struct address_space *mapping = page_mapping(page);
672 674
673 if (unlikely(!mapping)) 675 if (unlikely(!mapping))
@@ -683,11 +685,22 @@ int __set_page_dirty_buffers(struct page *page)
683 bh = bh->b_this_page; 685 bh = bh->b_this_page;
684 } while (bh != head); 686 } while (bh != head);
685 } 687 }
688 /*
689 * Use mem_group_begin_page_stat() to keep PageDirty synchronized with
690 * per-memcg dirty page counters.
691 */
692 memcg = mem_cgroup_begin_page_stat(page);
686 newly_dirty = !TestSetPageDirty(page); 693 newly_dirty = !TestSetPageDirty(page);
687 spin_unlock(&mapping->private_lock); 694 spin_unlock(&mapping->private_lock);
688 695
689 if (newly_dirty) 696 if (newly_dirty)
690 __set_page_dirty(page, mapping, 1); 697 __set_page_dirty(page, mapping, memcg, 1);
698
699 mem_cgroup_end_page_stat(memcg);
700
701 if (newly_dirty)
702 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
703
691 return newly_dirty; 704 return newly_dirty;
692} 705}
693EXPORT_SYMBOL(__set_page_dirty_buffers); 706EXPORT_SYMBOL(__set_page_dirty_buffers);
@@ -1158,11 +1171,18 @@ void mark_buffer_dirty(struct buffer_head *bh)
1158 1171
1159 if (!test_set_buffer_dirty(bh)) { 1172 if (!test_set_buffer_dirty(bh)) {
1160 struct page *page = bh->b_page; 1173 struct page *page = bh->b_page;
1174 struct address_space *mapping = NULL;
1175 struct mem_cgroup *memcg;
1176
1177 memcg = mem_cgroup_begin_page_stat(page);
1161 if (!TestSetPageDirty(page)) { 1178 if (!TestSetPageDirty(page)) {
1162 struct address_space *mapping = page_mapping(page); 1179 mapping = page_mapping(page);
1163 if (mapping) 1180 if (mapping)
1164 __set_page_dirty(page, mapping, 0); 1181 __set_page_dirty(page, mapping, memcg, 0);
1165 } 1182 }
1183 mem_cgroup_end_page_stat(memcg);
1184 if (mapping)
1185 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
1166 } 1186 }
1167} 1187}
1168EXPORT_SYMBOL(mark_buffer_dirty); 1188EXPORT_SYMBOL(mark_buffer_dirty);
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 095f94c2d8b5..e5099f268032 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -1873,6 +1873,7 @@ xfs_vm_set_page_dirty(
1873 loff_t end_offset; 1873 loff_t end_offset;
1874 loff_t offset; 1874 loff_t offset;
1875 int newly_dirty; 1875 int newly_dirty;
1876 struct mem_cgroup *memcg;
1876 1877
1877 if (unlikely(!mapping)) 1878 if (unlikely(!mapping))
1878 return !TestSetPageDirty(page); 1879 return !TestSetPageDirty(page);
@@ -1892,6 +1893,11 @@ xfs_vm_set_page_dirty(
1892 offset += 1 << inode->i_blkbits; 1893 offset += 1 << inode->i_blkbits;
1893 } while (bh != head); 1894 } while (bh != head);
1894 } 1895 }
1896 /*
1897 * Use mem_group_begin_page_stat() to keep PageDirty synchronized with
1898 * per-memcg dirty page counters.
1899 */
1900 memcg = mem_cgroup_begin_page_stat(page);
1895 newly_dirty = !TestSetPageDirty(page); 1901 newly_dirty = !TestSetPageDirty(page);
1896 spin_unlock(&mapping->private_lock); 1902 spin_unlock(&mapping->private_lock);
1897 1903
@@ -1902,13 +1908,15 @@ xfs_vm_set_page_dirty(
1902 spin_lock_irqsave(&mapping->tree_lock, flags); 1908 spin_lock_irqsave(&mapping->tree_lock, flags);
1903 if (page->mapping) { /* Race with truncate? */ 1909 if (page->mapping) { /* Race with truncate? */
1904 WARN_ON_ONCE(!PageUptodate(page)); 1910 WARN_ON_ONCE(!PageUptodate(page));
1905 account_page_dirtied(page, mapping); 1911 account_page_dirtied(page, mapping, memcg);
1906 radix_tree_tag_set(&mapping->page_tree, 1912 radix_tree_tag_set(&mapping->page_tree,
1907 page_index(page), PAGECACHE_TAG_DIRTY); 1913 page_index(page), PAGECACHE_TAG_DIRTY);
1908 } 1914 }
1909 spin_unlock_irqrestore(&mapping->tree_lock, flags); 1915 spin_unlock_irqrestore(&mapping->tree_lock, flags);
1910 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
1911 } 1916 }
1917 mem_cgroup_end_page_stat(memcg);
1918 if (newly_dirty)
1919 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
1912 return newly_dirty; 1920 return newly_dirty;
1913} 1921}
1914 1922
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 72dff5fb0d0c..5fe6411b5e54 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -41,6 +41,7 @@ enum mem_cgroup_stat_index {
41 MEM_CGROUP_STAT_RSS, /* # of pages charged as anon rss */ 41 MEM_CGROUP_STAT_RSS, /* # of pages charged as anon rss */
42 MEM_CGROUP_STAT_RSS_HUGE, /* # of pages charged as anon huge */ 42 MEM_CGROUP_STAT_RSS_HUGE, /* # of pages charged as anon huge */
43 MEM_CGROUP_STAT_FILE_MAPPED, /* # of pages charged as file rss */ 43 MEM_CGROUP_STAT_FILE_MAPPED, /* # of pages charged as file rss */
44 MEM_CGROUP_STAT_DIRTY, /* # of dirty pages in page cache */
44 MEM_CGROUP_STAT_WRITEBACK, /* # of pages under writeback */ 45 MEM_CGROUP_STAT_WRITEBACK, /* # of pages under writeback */
45 MEM_CGROUP_STAT_SWAP, /* # of pages, swapped out */ 46 MEM_CGROUP_STAT_SWAP, /* # of pages, swapped out */
46 MEM_CGROUP_STAT_NSTATS, 47 MEM_CGROUP_STAT_NSTATS,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index a83cf3a6f78e..f48d979ced4b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1211,8 +1211,10 @@ int __set_page_dirty_nobuffers(struct page *page);
1211int __set_page_dirty_no_writeback(struct page *page); 1211int __set_page_dirty_no_writeback(struct page *page);
1212int redirty_page_for_writepage(struct writeback_control *wbc, 1212int redirty_page_for_writepage(struct writeback_control *wbc,
1213 struct page *page); 1213 struct page *page);
1214void account_page_dirtied(struct page *page, struct address_space *mapping); 1214void account_page_dirtied(struct page *page, struct address_space *mapping,
1215void account_page_cleaned(struct page *page, struct address_space *mapping); 1215 struct mem_cgroup *memcg);
1216void account_page_cleaned(struct page *page, struct address_space *mapping,
1217 struct mem_cgroup *memcg);
1216int set_page_dirty(struct page *page); 1218int set_page_dirty(struct page *page);
1217int set_page_dirty_lock(struct page *page); 1219int set_page_dirty_lock(struct page *page);
1218void cancel_dirty_page(struct page *page); 1220void cancel_dirty_page(struct page *page);
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 4b3736f7065c..fb0814ca65c7 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -651,7 +651,8 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping,
651int add_to_page_cache_lru(struct page *page, struct address_space *mapping, 651int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
652 pgoff_t index, gfp_t gfp_mask); 652 pgoff_t index, gfp_t gfp_mask);
653extern void delete_from_page_cache(struct page *page); 653extern void delete_from_page_cache(struct page *page);
654extern void __delete_from_page_cache(struct page *page, void *shadow); 654extern void __delete_from_page_cache(struct page *page, void *shadow,
655 struct mem_cgroup *memcg);
655int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask); 656int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask);
656 657
657/* 658/*
diff --git a/mm/filemap.c b/mm/filemap.c
index 6bf5e42d560a..7b1443dc3ad0 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -100,6 +100,7 @@
100 * ->tree_lock (page_remove_rmap->set_page_dirty) 100 * ->tree_lock (page_remove_rmap->set_page_dirty)
101 * bdi.wb->list_lock (page_remove_rmap->set_page_dirty) 101 * bdi.wb->list_lock (page_remove_rmap->set_page_dirty)
102 * ->inode->i_lock (page_remove_rmap->set_page_dirty) 102 * ->inode->i_lock (page_remove_rmap->set_page_dirty)
103 * ->memcg->move_lock (page_remove_rmap->mem_cgroup_begin_page_stat)
103 * bdi.wb->list_lock (zap_pte_range->set_page_dirty) 104 * bdi.wb->list_lock (zap_pte_range->set_page_dirty)
104 * ->inode->i_lock (zap_pte_range->set_page_dirty) 105 * ->inode->i_lock (zap_pte_range->set_page_dirty)
105 * ->private_lock (zap_pte_range->__set_page_dirty_buffers) 106 * ->private_lock (zap_pte_range->__set_page_dirty_buffers)
@@ -174,9 +175,11 @@ static void page_cache_tree_delete(struct address_space *mapping,
174/* 175/*
175 * Delete a page from the page cache and free it. Caller has to make 176 * Delete a page from the page cache and free it. Caller has to make
176 * sure the page is locked and that nobody else uses it - or that usage 177 * sure the page is locked and that nobody else uses it - or that usage
177 * is safe. The caller must hold the mapping's tree_lock. 178 * is safe. The caller must hold the mapping's tree_lock and
179 * mem_cgroup_begin_page_stat().
178 */ 180 */
179void __delete_from_page_cache(struct page *page, void *shadow) 181void __delete_from_page_cache(struct page *page, void *shadow,
182 struct mem_cgroup *memcg)
180{ 183{
181 struct address_space *mapping = page->mapping; 184 struct address_space *mapping = page->mapping;
182 185
@@ -210,7 +213,7 @@ void __delete_from_page_cache(struct page *page, void *shadow)
210 * anyway will be cleared before returning page into buddy allocator. 213 * anyway will be cleared before returning page into buddy allocator.
211 */ 214 */
212 if (WARN_ON_ONCE(PageDirty(page))) 215 if (WARN_ON_ONCE(PageDirty(page)))
213 account_page_cleaned(page, mapping); 216 account_page_cleaned(page, mapping, memcg);
214} 217}
215 218
216/** 219/**
@@ -224,14 +227,20 @@ void __delete_from_page_cache(struct page *page, void *shadow)
224void delete_from_page_cache(struct page *page) 227void delete_from_page_cache(struct page *page)
225{ 228{
226 struct address_space *mapping = page->mapping; 229 struct address_space *mapping = page->mapping;
230 struct mem_cgroup *memcg;
231 unsigned long flags;
232
227 void (*freepage)(struct page *); 233 void (*freepage)(struct page *);
228 234
229 BUG_ON(!PageLocked(page)); 235 BUG_ON(!PageLocked(page));
230 236
231 freepage = mapping->a_ops->freepage; 237 freepage = mapping->a_ops->freepage;
232 spin_lock_irq(&mapping->tree_lock); 238
233 __delete_from_page_cache(page, NULL); 239 memcg = mem_cgroup_begin_page_stat(page);
234 spin_unlock_irq(&mapping->tree_lock); 240 spin_lock_irqsave(&mapping->tree_lock, flags);
241 __delete_from_page_cache(page, NULL, memcg);
242 spin_unlock_irqrestore(&mapping->tree_lock, flags);
243 mem_cgroup_end_page_stat(memcg);
235 244
236 if (freepage) 245 if (freepage)
237 freepage(page); 246 freepage(page);
@@ -470,6 +479,8 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
470 if (!error) { 479 if (!error) {
471 struct address_space *mapping = old->mapping; 480 struct address_space *mapping = old->mapping;
472 void (*freepage)(struct page *); 481 void (*freepage)(struct page *);
482 struct mem_cgroup *memcg;
483 unsigned long flags;
473 484
474 pgoff_t offset = old->index; 485 pgoff_t offset = old->index;
475 freepage = mapping->a_ops->freepage; 486 freepage = mapping->a_ops->freepage;
@@ -478,15 +489,17 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
478 new->mapping = mapping; 489 new->mapping = mapping;
479 new->index = offset; 490 new->index = offset;
480 491
481 spin_lock_irq(&mapping->tree_lock); 492 memcg = mem_cgroup_begin_page_stat(old);
482 __delete_from_page_cache(old, NULL); 493 spin_lock_irqsave(&mapping->tree_lock, flags);
494 __delete_from_page_cache(old, NULL, memcg);
483 error = radix_tree_insert(&mapping->page_tree, offset, new); 495 error = radix_tree_insert(&mapping->page_tree, offset, new);
484 BUG_ON(error); 496 BUG_ON(error);
485 mapping->nrpages++; 497 mapping->nrpages++;
486 __inc_zone_page_state(new, NR_FILE_PAGES); 498 __inc_zone_page_state(new, NR_FILE_PAGES);
487 if (PageSwapBacked(new)) 499 if (PageSwapBacked(new))
488 __inc_zone_page_state(new, NR_SHMEM); 500 __inc_zone_page_state(new, NR_SHMEM);
489 spin_unlock_irq(&mapping->tree_lock); 501 spin_unlock_irqrestore(&mapping->tree_lock, flags);
502 mem_cgroup_end_page_stat(memcg);
490 mem_cgroup_migrate(old, new, true); 503 mem_cgroup_migrate(old, new, true);
491 radix_tree_preload_end(); 504 radix_tree_preload_end();
492 if (freepage) 505 if (freepage)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 14c2f2017e37..c23c1a3e8e16 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -90,6 +90,7 @@ static const char * const mem_cgroup_stat_names[] = {
90 "rss", 90 "rss",
91 "rss_huge", 91 "rss_huge",
92 "mapped_file", 92 "mapped_file",
93 "dirty",
93 "writeback", 94 "writeback",
94 "swap", 95 "swap",
95}; 96};
@@ -2011,6 +2012,7 @@ again:
2011 2012
2012 return memcg; 2013 return memcg;
2013} 2014}
2015EXPORT_SYMBOL(mem_cgroup_begin_page_stat);
2014 2016
2015/** 2017/**
2016 * mem_cgroup_end_page_stat - finish a page state statistics transaction 2018 * mem_cgroup_end_page_stat - finish a page state statistics transaction
@@ -2029,6 +2031,7 @@ void mem_cgroup_end_page_stat(struct mem_cgroup *memcg)
2029 2031
2030 rcu_read_unlock(); 2032 rcu_read_unlock();
2031} 2033}
2034EXPORT_SYMBOL(mem_cgroup_end_page_stat);
2032 2035
2033/** 2036/**
2034 * mem_cgroup_update_page_stat - update page state statistics 2037 * mem_cgroup_update_page_stat - update page state statistics
@@ -4746,6 +4749,7 @@ static int mem_cgroup_move_account(struct page *page,
4746{ 4749{
4747 unsigned long flags; 4750 unsigned long flags;
4748 int ret; 4751 int ret;
4752 bool anon;
4749 4753
4750 VM_BUG_ON(from == to); 4754 VM_BUG_ON(from == to);
4751 VM_BUG_ON_PAGE(PageLRU(page), page); 4755 VM_BUG_ON_PAGE(PageLRU(page), page);
@@ -4771,15 +4775,33 @@ static int mem_cgroup_move_account(struct page *page,
4771 if (page->mem_cgroup != from) 4775 if (page->mem_cgroup != from)
4772 goto out_unlock; 4776 goto out_unlock;
4773 4777
4778 anon = PageAnon(page);
4779
4774 spin_lock_irqsave(&from->move_lock, flags); 4780 spin_lock_irqsave(&from->move_lock, flags);
4775 4781
4776 if (!PageAnon(page) && page_mapped(page)) { 4782 if (!anon && page_mapped(page)) {
4777 __this_cpu_sub(from->stat->count[MEM_CGROUP_STAT_FILE_MAPPED], 4783 __this_cpu_sub(from->stat->count[MEM_CGROUP_STAT_FILE_MAPPED],
4778 nr_pages); 4784 nr_pages);
4779 __this_cpu_add(to->stat->count[MEM_CGROUP_STAT_FILE_MAPPED], 4785 __this_cpu_add(to->stat->count[MEM_CGROUP_STAT_FILE_MAPPED],
4780 nr_pages); 4786 nr_pages);
4781 } 4787 }
4782 4788
4789 /*
4790 * move_lock grabbed above and caller set from->moving_account, so
4791 * mem_cgroup_update_page_stat() will serialize updates to PageDirty.
4792 * So mapping should be stable for dirty pages.
4793 */
4794 if (!anon && PageDirty(page)) {
4795 struct address_space *mapping = page_mapping(page);
4796
4797 if (mapping_cap_account_dirty(mapping)) {
4798 __this_cpu_sub(from->stat->count[MEM_CGROUP_STAT_DIRTY],
4799 nr_pages);
4800 __this_cpu_add(to->stat->count[MEM_CGROUP_STAT_DIRTY],
4801 nr_pages);
4802 }
4803 }
4804
4783 if (PageWriteback(page)) { 4805 if (PageWriteback(page)) {
4784 __this_cpu_sub(from->stat->count[MEM_CGROUP_STAT_WRITEBACK], 4806 __this_cpu_sub(from->stat->count[MEM_CGROUP_STAT_WRITEBACK],
4785 nr_pages); 4807 nr_pages);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 227b867598e1..bdeecad00489 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2090,15 +2090,20 @@ int __set_page_dirty_no_writeback(struct page *page)
2090 2090
2091/* 2091/*
2092 * Helper function for set_page_dirty family. 2092 * Helper function for set_page_dirty family.
2093 *
2094 * Caller must hold mem_cgroup_begin_page_stat().
2095 *
2093 * NOTE: This relies on being atomic wrt interrupts. 2096 * NOTE: This relies on being atomic wrt interrupts.
2094 */ 2097 */
2095void account_page_dirtied(struct page *page, struct address_space *mapping) 2098void account_page_dirtied(struct page *page, struct address_space *mapping,
2099 struct mem_cgroup *memcg)
2096{ 2100{
2097 trace_writeback_dirty_page(page, mapping); 2101 trace_writeback_dirty_page(page, mapping);
2098 2102
2099 if (mapping_cap_account_dirty(mapping)) { 2103 if (mapping_cap_account_dirty(mapping)) {
2100 struct backing_dev_info *bdi = inode_to_bdi(mapping->host); 2104 struct backing_dev_info *bdi = inode_to_bdi(mapping->host);
2101 2105
2106 mem_cgroup_inc_page_stat(memcg, MEM_CGROUP_STAT_DIRTY);
2102 __inc_zone_page_state(page, NR_FILE_DIRTY); 2107 __inc_zone_page_state(page, NR_FILE_DIRTY);
2103 __inc_zone_page_state(page, NR_DIRTIED); 2108 __inc_zone_page_state(page, NR_DIRTIED);
2104 __inc_bdi_stat(bdi, BDI_RECLAIMABLE); 2109 __inc_bdi_stat(bdi, BDI_RECLAIMABLE);
@@ -2112,10 +2117,14 @@ EXPORT_SYMBOL(account_page_dirtied);
2112 2117
2113/* 2118/*
2114 * Helper function for deaccounting dirty page without writeback. 2119 * Helper function for deaccounting dirty page without writeback.
2120 *
2121 * Caller must hold mem_cgroup_begin_page_stat().
2115 */ 2122 */
2116void account_page_cleaned(struct page *page, struct address_space *mapping) 2123void account_page_cleaned(struct page *page, struct address_space *mapping,
2124 struct mem_cgroup *memcg)
2117{ 2125{
2118 if (mapping_cap_account_dirty(mapping)) { 2126 if (mapping_cap_account_dirty(mapping)) {
2127 mem_cgroup_dec_page_stat(memcg, MEM_CGROUP_STAT_DIRTY);
2119 dec_zone_page_state(page, NR_FILE_DIRTY); 2128 dec_zone_page_state(page, NR_FILE_DIRTY);
2120 dec_bdi_stat(inode_to_bdi(mapping->host), BDI_RECLAIMABLE); 2129 dec_bdi_stat(inode_to_bdi(mapping->host), BDI_RECLAIMABLE);
2121 task_io_account_cancelled_write(PAGE_CACHE_SIZE); 2130 task_io_account_cancelled_write(PAGE_CACHE_SIZE);
@@ -2136,26 +2145,34 @@ void account_page_cleaned(struct page *page, struct address_space *mapping)
2136 */ 2145 */
2137int __set_page_dirty_nobuffers(struct page *page) 2146int __set_page_dirty_nobuffers(struct page *page)
2138{ 2147{
2148 struct mem_cgroup *memcg;
2149
2150 memcg = mem_cgroup_begin_page_stat(page);
2139 if (!TestSetPageDirty(page)) { 2151 if (!TestSetPageDirty(page)) {
2140 struct address_space *mapping = page_mapping(page); 2152 struct address_space *mapping = page_mapping(page);
2141 unsigned long flags; 2153 unsigned long flags;
2142 2154
2143 if (!mapping) 2155 if (!mapping) {
2156 mem_cgroup_end_page_stat(memcg);
2144 return 1; 2157 return 1;
2158 }
2145 2159
2146 spin_lock_irqsave(&mapping->tree_lock, flags); 2160 spin_lock_irqsave(&mapping->tree_lock, flags);
2147 BUG_ON(page_mapping(page) != mapping); 2161 BUG_ON(page_mapping(page) != mapping);
2148 WARN_ON_ONCE(!PagePrivate(page) && !PageUptodate(page)); 2162 WARN_ON_ONCE(!PagePrivate(page) && !PageUptodate(page));
2149 account_page_dirtied(page, mapping); 2163 account_page_dirtied(page, mapping, memcg);
2150 radix_tree_tag_set(&mapping->page_tree, page_index(page), 2164 radix_tree_tag_set(&mapping->page_tree, page_index(page),
2151 PAGECACHE_TAG_DIRTY); 2165 PAGECACHE_TAG_DIRTY);
2152 spin_unlock_irqrestore(&mapping->tree_lock, flags); 2166 spin_unlock_irqrestore(&mapping->tree_lock, flags);
2167 mem_cgroup_end_page_stat(memcg);
2168
2153 if (mapping->host) { 2169 if (mapping->host) {
2154 /* !PageAnon && !swapper_space */ 2170 /* !PageAnon && !swapper_space */
2155 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); 2171 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
2156 } 2172 }
2157 return 1; 2173 return 1;
2158 } 2174 }
2175 mem_cgroup_end_page_stat(memcg);
2159 return 0; 2176 return 0;
2160} 2177}
2161EXPORT_SYMBOL(__set_page_dirty_nobuffers); 2178EXPORT_SYMBOL(__set_page_dirty_nobuffers);
@@ -2273,8 +2290,20 @@ EXPORT_SYMBOL(set_page_dirty_lock);
2273 */ 2290 */
2274void cancel_dirty_page(struct page *page) 2291void cancel_dirty_page(struct page *page)
2275{ 2292{
2276 if (TestClearPageDirty(page)) 2293 struct address_space *mapping = page_mapping(page);
2277 account_page_cleaned(page, page_mapping(page)); 2294
2295 if (mapping_cap_account_dirty(mapping)) {
2296 struct mem_cgroup *memcg;
2297
2298 memcg = mem_cgroup_begin_page_stat(page);
2299
2300 if (TestClearPageDirty(page))
2301 account_page_cleaned(page, mapping, memcg);
2302
2303 mem_cgroup_end_page_stat(memcg);
2304 } else {
2305 ClearPageDirty(page);
2306 }
2278} 2307}
2279EXPORT_SYMBOL(cancel_dirty_page); 2308EXPORT_SYMBOL(cancel_dirty_page);
2280 2309
@@ -2295,6 +2324,8 @@ EXPORT_SYMBOL(cancel_dirty_page);
2295int clear_page_dirty_for_io(struct page *page) 2324int clear_page_dirty_for_io(struct page *page)
2296{ 2325{
2297 struct address_space *mapping = page_mapping(page); 2326 struct address_space *mapping = page_mapping(page);
2327 struct mem_cgroup *memcg;
2328 int ret = 0;
2298 2329
2299 BUG_ON(!PageLocked(page)); 2330 BUG_ON(!PageLocked(page));
2300 2331
@@ -2334,13 +2365,16 @@ int clear_page_dirty_for_io(struct page *page)
2334 * always locked coming in here, so we get the desired 2365 * always locked coming in here, so we get the desired
2335 * exclusion. 2366 * exclusion.
2336 */ 2367 */
2368 memcg = mem_cgroup_begin_page_stat(page);
2337 if (TestClearPageDirty(page)) { 2369 if (TestClearPageDirty(page)) {
2370 mem_cgroup_dec_page_stat(memcg, MEM_CGROUP_STAT_DIRTY);
2338 dec_zone_page_state(page, NR_FILE_DIRTY); 2371 dec_zone_page_state(page, NR_FILE_DIRTY);
2339 dec_bdi_stat(inode_to_bdi(mapping->host), 2372 dec_bdi_stat(inode_to_bdi(mapping->host),
2340 BDI_RECLAIMABLE); 2373 BDI_RECLAIMABLE);
2341 return 1; 2374 ret = 1;
2342 } 2375 }
2343 return 0; 2376 mem_cgroup_end_page_stat(memcg);
2377 return ret;
2344 } 2378 }
2345 return TestClearPageDirty(page); 2379 return TestClearPageDirty(page);
2346} 2380}
diff --git a/mm/rmap.c b/mm/rmap.c
index 24dd3f9fee27..8fc556ce2dcb 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -30,6 +30,8 @@
30 * swap_lock (in swap_duplicate, swap_info_get) 30 * swap_lock (in swap_duplicate, swap_info_get)
31 * mmlist_lock (in mmput, drain_mmlist and others) 31 * mmlist_lock (in mmput, drain_mmlist and others)
32 * mapping->private_lock (in __set_page_dirty_buffers) 32 * mapping->private_lock (in __set_page_dirty_buffers)
33 * mem_cgroup_{begin,end}_page_stat (memcg->move_lock)
34 * mapping->tree_lock (widely used)
33 * inode->i_lock (in set_page_dirty's __mark_inode_dirty) 35 * inode->i_lock (in set_page_dirty's __mark_inode_dirty)
34 * bdi.wb->list_lock (in set_page_dirty's __mark_inode_dirty) 36 * bdi.wb->list_lock (in set_page_dirty's __mark_inode_dirty)
35 * sb_lock (within inode_lock in fs/fs-writeback.c) 37 * sb_lock (within inode_lock in fs/fs-writeback.c)
diff --git a/mm/truncate.c b/mm/truncate.c
index 0c360259c085..76e35ad97102 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -510,19 +510,24 @@ EXPORT_SYMBOL(invalidate_mapping_pages);
510static int 510static int
511invalidate_complete_page2(struct address_space *mapping, struct page *page) 511invalidate_complete_page2(struct address_space *mapping, struct page *page)
512{ 512{
513 struct mem_cgroup *memcg;
514 unsigned long flags;
515
513 if (page->mapping != mapping) 516 if (page->mapping != mapping)
514 return 0; 517 return 0;
515 518
516 if (page_has_private(page) && !try_to_release_page(page, GFP_KERNEL)) 519 if (page_has_private(page) && !try_to_release_page(page, GFP_KERNEL))
517 return 0; 520 return 0;
518 521
519 spin_lock_irq(&mapping->tree_lock); 522 memcg = mem_cgroup_begin_page_stat(page);
523 spin_lock_irqsave(&mapping->tree_lock, flags);
520 if (PageDirty(page)) 524 if (PageDirty(page))
521 goto failed; 525 goto failed;
522 526
523 BUG_ON(page_has_private(page)); 527 BUG_ON(page_has_private(page));
524 __delete_from_page_cache(page, NULL); 528 __delete_from_page_cache(page, NULL, memcg);
525 spin_unlock_irq(&mapping->tree_lock); 529 spin_unlock_irqrestore(&mapping->tree_lock, flags);
530 mem_cgroup_end_page_stat(memcg);
526 531
527 if (mapping->a_ops->freepage) 532 if (mapping->a_ops->freepage)
528 mapping->a_ops->freepage(page); 533 mapping->a_ops->freepage(page);
@@ -530,7 +535,8 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
530 page_cache_release(page); /* pagecache ref */ 535 page_cache_release(page); /* pagecache ref */
531 return 1; 536 return 1;
532failed: 537failed:
533 spin_unlock_irq(&mapping->tree_lock); 538 spin_unlock_irqrestore(&mapping->tree_lock, flags);
539 mem_cgroup_end_page_stat(memcg);
534 return 0; 540 return 0;
535} 541}
536 542
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 5e8eadd71bac..7582f9fcda92 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -579,10 +579,14 @@ static pageout_t pageout(struct page *page, struct address_space *mapping,
579static int __remove_mapping(struct address_space *mapping, struct page *page, 579static int __remove_mapping(struct address_space *mapping, struct page *page,
580 bool reclaimed) 580 bool reclaimed)
581{ 581{
582 unsigned long flags;
583 struct mem_cgroup *memcg;
584
582 BUG_ON(!PageLocked(page)); 585 BUG_ON(!PageLocked(page));
583 BUG_ON(mapping != page_mapping(page)); 586 BUG_ON(mapping != page_mapping(page));
584 587
585 spin_lock_irq(&mapping->tree_lock); 588 memcg = mem_cgroup_begin_page_stat(page);
589 spin_lock_irqsave(&mapping->tree_lock, flags);
586 /* 590 /*
587 * The non racy check for a busy page. 591 * The non racy check for a busy page.
588 * 592 *
@@ -620,7 +624,8 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
620 swp_entry_t swap = { .val = page_private(page) }; 624 swp_entry_t swap = { .val = page_private(page) };
621 mem_cgroup_swapout(page, swap); 625 mem_cgroup_swapout(page, swap);
622 __delete_from_swap_cache(page); 626 __delete_from_swap_cache(page);
623 spin_unlock_irq(&mapping->tree_lock); 627 spin_unlock_irqrestore(&mapping->tree_lock, flags);
628 mem_cgroup_end_page_stat(memcg);
624 swapcache_free(swap); 629 swapcache_free(swap);
625 } else { 630 } else {
626 void (*freepage)(struct page *); 631 void (*freepage)(struct page *);
@@ -640,8 +645,9 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
640 if (reclaimed && page_is_file_cache(page) && 645 if (reclaimed && page_is_file_cache(page) &&
641 !mapping_exiting(mapping)) 646 !mapping_exiting(mapping))
642 shadow = workingset_eviction(mapping, page); 647 shadow = workingset_eviction(mapping, page);
643 __delete_from_page_cache(page, shadow); 648 __delete_from_page_cache(page, shadow, memcg);
644 spin_unlock_irq(&mapping->tree_lock); 649 spin_unlock_irqrestore(&mapping->tree_lock, flags);
650 mem_cgroup_end_page_stat(memcg);
645 651
646 if (freepage != NULL) 652 if (freepage != NULL)
647 freepage(page); 653 freepage(page);
@@ -650,7 +656,8 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
650 return 1; 656 return 1;
651 657
652cannot_free: 658cannot_free:
653 spin_unlock_irq(&mapping->tree_lock); 659 spin_unlock_irqrestore(&mapping->tree_lock, flags);
660 mem_cgroup_end_page_stat(memcg);
654 return 0; 661 return 0;
655} 662}
656 663