mm: move accounting updates before page_cache_tree_delete()
authorJan Kara <jack@suse.cz>
Thu, 16 Nov 2017 01:37:22 +0000 (17:37 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Nov 2017 02:21:06 +0000 (18:21 -0800)
Move updates of various counters before page_cache_tree_delete() call.
It will be easier to batch things this way and there is no difference
whether the counters get updated before or after removal from the radix
tree.

Link: http://lkml.kernel.org/r/20171010151937.26984-5-jack@suse.cz
Signed-off-by: Jan Kara <jack@suse.cz>
Acked-by: Mel Gorman <mgorman@suse.de>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/filemap.c

index ecf7565ff435778788a7f4b89dea8865f7323700..014109e66e4a59875fcd4665ddd7e584fb41d3fb 100644 (file)
@@ -224,34 +224,35 @@ void __delete_from_page_cache(struct page *page, void *shadow)
                }
        }
 
-       page_cache_tree_delete(mapping, page, shadow);
-
-       page->mapping = NULL;
-       /* Leave page->index set: truncation lookup relies upon it */
-
        /* hugetlb pages do not participate in page cache accounting. */
-       if (PageHuge(page))
-               return;
+       if (!PageHuge(page)) {
+               __mod_node_page_state(page_pgdat(page), NR_FILE_PAGES, -nr);
+               if (PageSwapBacked(page)) {
+                       __mod_node_page_state(page_pgdat(page), NR_SHMEM, -nr);
+                       if (PageTransHuge(page))
+                               __dec_node_page_state(page, NR_SHMEM_THPS);
+               } else {
+                       VM_BUG_ON_PAGE(PageTransHuge(page), page);
+               }
 
-       __mod_node_page_state(page_pgdat(page), NR_FILE_PAGES, -nr);
-       if (PageSwapBacked(page)) {
-               __mod_node_page_state(page_pgdat(page), NR_SHMEM, -nr);
-               if (PageTransHuge(page))
-                       __dec_node_page_state(page, NR_SHMEM_THPS);
-       } else {
-               VM_BUG_ON_PAGE(PageTransHuge(page), page);
+               /*
+                * At this point page must be either written or cleaned by
+                * truncate.  Dirty page here signals a bug and loss of
+                * unwritten data.
+                *
+                * This fixes dirty accounting after removing the page entirely
+                * but leaves PageDirty set: it has no effect for truncated
+                * page and anyway will be cleared before returning page into
+                * buddy allocator.
+                */
+               if (WARN_ON_ONCE(PageDirty(page)))
+                       account_page_cleaned(page, mapping,
+                                            inode_to_wb(mapping->host));
        }
+       page_cache_tree_delete(mapping, page, shadow);
 
-       /*
-        * At this point page must be either written or cleaned by truncate.
-        * Dirty page here signals a bug and loss of unwritten data.
-        *
-        * This fixes dirty accounting after removing the page entirely but
-        * leaves PageDirty set: it has no effect for truncated page and
-        * anyway will be cleared before returning page into buddy allocator.
-        */
-       if (WARN_ON_ONCE(PageDirty(page)))
-               account_page_cleaned(page, mapping, inode_to_wb(mapping->host));
+       page->mapping = NULL;
+       /* Leave page->index set: truncation lookup relies upon it */
 }
 
 static void page_cache_free_page(struct address_space *mapping,