mm: more likely reclaim MADV_SEQUENTIAL mappings
[sfrench/cifs-2.6.git] / mm / rmap.c
index 10993942d6c989314477291520c6bb6980a0439d..f01e92244c532b96c0214f316f973369eed6ee50 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -50,6 +50,7 @@
 #include <linux/kallsyms.h>
 #include <linux/memcontrol.h>
 #include <linux/mmu_notifier.h>
+#include <linux/migrate.h>
 
 #include <asm/tlbflush.h>
 
@@ -359,8 +360,17 @@ static int page_referenced_one(struct page *page,
                goto out_unmap;
        }
 
-       if (ptep_clear_flush_young_notify(vma, address, pte))
-               referenced++;
+       if (ptep_clear_flush_young_notify(vma, address, pte)) {
+               /*
+                * Don't treat a reference through a sequentially read
+                * mapping as such.  If the page has been used in
+                * another mapping, we will catch it; if this other
+                * mapping is already gone, the unmap path will have
+                * set PG_referenced or activated the page.
+                */
+               if (likely(!VM_SequentialReadHint(vma)))
+                       referenced++;
+       }
 
        /* Pretend the page is referenced if the task has the
           swap token and is in the middle of a page fault. */
@@ -818,8 +828,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
                                spin_unlock(&mmlist_lock);
                        }
                        dec_mm_counter(mm, anon_rss);
-#ifdef CONFIG_MIGRATION
-               } else {
+               } else if (PAGE_MIGRATION) {
                        /*
                         * Store the pfn of the page in a special migration
                         * pte. do_swap_page() will wait until the migration
@@ -827,19 +836,15 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
                         */
                        BUG_ON(!migration);
                        entry = make_migration_entry(page, pte_write(pteval));
-#endif
                }
                set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
                BUG_ON(pte_file(*pte));
-       } else
-#ifdef CONFIG_MIGRATION
-       if (migration) {
+       } else if (PAGE_MIGRATION && migration) {
                /* Establish migration entry for a file page */
                swp_entry_t entry;
                entry = make_migration_entry(page, pte_write(pteval));
                set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
        } else
-#endif
                dec_mm_counter(mm, file_rss);