*/
/*
- * Locking:
- * - the page->mapcount field is protected by the PG_maplock bit,
- * which nests within the mm->page_table_lock,
- * which nests within the page lock.
- * - because swapout locking is opposite to the locking order
- * in the page fault path, the swapout path uses trylocks
- * on the mm->page_table_lock
+ * Locking: see "Lock ordering" summary in filemap.c.
+ * In swapout, page_map_lock is held on entry to page_referenced and
+ * try_to_unmap, so they trylock for i_mmap_lock and page_table_lock.
*/
+
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/rmap.h>
+#include <linux/vs_memory.h>
#include <asm/tlbflush.h>
/* page_table_lock to protect against threads */
spin_lock(&mm->page_table_lock);
if (likely(!vma->anon_vma)) {
+ if (!allocated)
+ spin_lock(&anon_vma->lock);
vma->anon_vma = anon_vma;
list_add(&vma->anon_vma_node, &anon_vma->head);
+ if (!allocated)
+ spin_unlock(&anon_vma->lock);
allocated = NULL;
}
spin_unlock(&mm->page_table_lock);
if (page_to_pfn(page) != pte_pfn(*pte))
goto out_unmap;
- if (ptep_test_and_clear_young(pte))
+ if (ptep_clear_flush_young(vma, address, pte))
referenced++;
(*mapcount)--;
* skipped over this mm) then we should reactivate it.
*/
if ((vma->vm_flags & (VM_LOCKED|VM_RESERVED)) ||
- ptep_test_and_clear_young(pte)) {
+ ptep_clear_flush_young(vma, address, pte)) {
ret = SWAP_FAIL;
goto out_unmap;
}
BUG_ON(pte_file(*pte));
}
- mm->rss--;
+ // mm->rss--;
+ vx_rsspages_dec(mm);
BUG_ON(!page->mapcount);
page->mapcount--;
page_cache_release(page);
if (PageReserved(page))
continue;
- if (ptep_test_and_clear_young(pte))
+ if (ptep_clear_flush_young(vma, address, pte))
continue;
/* Nuke the page table entry. */
list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
shared.vm_set.list) {
if (!(vma->vm_flags & VM_RESERVED))
- vma->vm_private_data = 0;
+ vma->vm_private_data = NULL;
}
relock:
page_map_lock(page);