mm: workingset: restore refault tracking for single-page files
authorJohannes Weiner <hannes@cmpxchg.org>
Tue, 13 Dec 2016 00:43:55 +0000 (16:43 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Dec 2016 02:55:08 +0000 (18:55 -0800)
Shadow entries in the page cache used to be accounted behind the radix
tree implementation's back in the upper bits of node->count, and the
radix tree code extending a single-entry tree with a shadow entry in
root->rnode would corrupt that counter.  As a result, we could not put
shadow entries at index 0 if the tree didn't have any other entries, and
that means no refault detection for any single-page file.

Now that the shadow entries are tracked natively in the radix tree's
exceptional counter, this is no longer necessary.  Extending and
shrinking the tree from and to single entries in root->rnode now does
the right thing when the entry is exceptional, remove that limitation.

Link: http://lkml.kernel.org/r/20161117193244.GF23430@cmpxchg.org
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Matthew Wilcox <mawilcox@linuxonhyperv.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/filemap.c

index dc3e5fce0b7b0f4217757ed0c418b43070bb0908..5b4dd03130da33b91cca705e6d202fffed177b55 100644 (file)
@@ -167,14 +167,7 @@ static void page_cache_tree_delete(struct address_space *mapping,
                __radix_tree_lookup(&mapping->page_tree, page->index + i,
                                    &node, &slot);
 
-               if (!node) {
-                       VM_BUG_ON_PAGE(nr != 1, page);
-                       /*
-                        * We need a node to properly account shadow
-                        * entries. Don't plant any without. XXX
-                        */
-                       shadow = NULL;
-               }
+               VM_BUG_ON_PAGE(!node && nr != 1, page);
 
                radix_tree_clear_tags(&mapping->page_tree, node, slot);
                __radix_tree_replace(&mapping->page_tree, node, slot, shadow,