[PATCH] Use Zoned VM Counters for NUMA statistics
[pandora-kernel.git] / mm / rmap.c
index 3b8ce86..40158b5 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -205,44 +205,6 @@ out:
        return anon_vma;
 }
 
-#ifdef CONFIG_MIGRATION
-/*
- * Remove an anonymous page from swap replacing the swap pte's
- * through real pte's pointing to valid pages and then releasing
- * the page from the swap cache.
- *
- * Must hold page lock on page and mmap_sem of one vma that contains
- * the page.
- */
-void remove_from_swap(struct page *page)
-{
-       struct anon_vma *anon_vma;
-       struct vm_area_struct *vma;
-       unsigned long mapping;
-
-       if (!PageSwapCache(page))
-               return;
-
-       mapping = (unsigned long)page->mapping;
-
-       if (!mapping || (mapping & PAGE_MAPPING_ANON) == 0)
-               return;
-
-       /*
-        * We hold the mmap_sem lock. So no need to call page_lock_anon_vma.
-        */
-       anon_vma = (struct anon_vma *) (mapping - PAGE_MAPPING_ANON);
-       spin_lock(&anon_vma->lock);
-
-       list_for_each_entry(vma, &anon_vma->head, anon_vma_node)
-               remove_vma_swap(vma, page);
-
-       spin_unlock(&anon_vma->lock);
-       delete_from_swap_cache(page);
-}
-EXPORT_SYMBOL(remove_from_swap);
-#endif
-
 /*
  * At what user virtual address is page expected in vma?
  */
@@ -493,7 +455,7 @@ static void __page_set_anon_rmap(struct page *page,
         * nr_mapped state can be updated without turning off
         * interrupts because it is not modified via interrupt.
         */
-       __inc_page_state(nr_mapped);
+       __inc_zone_page_state(page, NR_ANON_PAGES);
 }
 
 /**
@@ -537,7 +499,7 @@ void page_add_new_anon_rmap(struct page *page,
 void page_add_file_rmap(struct page *page)
 {
        if (atomic_inc_and_test(&page->_mapcount))
-               __inc_page_state(nr_mapped);
+               __inc_zone_page_state(page, NR_FILE_MAPPED);
 }
 
 /**
@@ -569,7 +531,8 @@ void page_remove_rmap(struct page *page)
                 */
                if (page_test_and_clear_dirty(page))
                        set_page_dirty(page);
-               __dec_page_state(nr_mapped);
+               __dec_zone_page_state(page,
+                               PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED);
        }
 }
 
@@ -600,9 +563,8 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
         * If it's recently referenced (perhaps page_referenced
         * skipped over this mm) then we should reactivate it.
         */
-       if ((vma->vm_flags & VM_LOCKED) ||
-                       (ptep_clear_flush_young(vma, address, pte)
-                               && !migration)) {
+       if (!migration && ((vma->vm_flags & VM_LOCKED) ||
+                       (ptep_clear_flush_young(vma, address, pte)))) {
                ret = SWAP_FAIL;
                goto out_unmap;
        }
@@ -633,6 +595,8 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
                                        list_add(&mm->mmlist, &init_mm.mmlist);
                                spin_unlock(&mmlist_lock);
                        }
+                       dec_mm_counter(mm, anon_rss);
+#ifdef CONFIG_MIGRATION
                } else {
                        /*
                         * Store the pfn of the page in a special migration
@@ -641,13 +605,22 @@ 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));
-               dec_mm_counter(mm, anon_rss);
        } else
+#ifdef CONFIG_MIGRATION
+       if (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);
 
+
        page_remove_rmap(page);
        page_cache_release(page);
 
@@ -798,7 +771,7 @@ static int try_to_unmap_file(struct page *page, int migration)
 
        list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
                                                shared.vm_set.list) {
-               if (vma->vm_flags & VM_LOCKED)
+               if ((vma->vm_flags & VM_LOCKED) && !migration)
                        continue;
                cursor = (unsigned long) vma->vm_private_data;
                if (cursor > max_nl_cursor)
@@ -832,7 +805,7 @@ static int try_to_unmap_file(struct page *page, int migration)
        do {
                list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
                                                shared.vm_set.list) {
-                       if (vma->vm_flags & VM_LOCKED)
+                       if ((vma->vm_flags & VM_LOCKED) && !migration)
                                continue;
                        cursor = (unsigned long) vma->vm_private_data;
                        while ( cursor < max_nl_cursor &&