mm: don't waste swap on locked pages
[pandora-kernel.git] / mm / rmap.c
index 8990f90..57ad276 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -36,7 +36,6 @@
  *                 mapping->tree_lock (widely used, in set_page_dirty,
  *                           in arch-dependent flush_dcache_mmap_lock,
  *                           within inode_lock in __sync_single_inode)
- *                   zone->lock (within radix tree node alloc)
  */
 
 #include <linux/mm.h>
@@ -183,7 +182,9 @@ static void page_unlock_anon_vma(struct anon_vma *anon_vma)
 }
 
 /*
- * At what user virtual address is page expected in vma?
+ * At what user virtual address is page expected in @vma?
+ * Returns virtual address or -EFAULT if page's index/offset is not
+ * within the range mapped the @vma.
  */
 static inline unsigned long
 vma_address(struct page *page, struct vm_area_struct *vma)
@@ -193,8 +194,7 @@ vma_address(struct page *page, struct vm_area_struct *vma)
 
        address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
        if (unlikely(address < vma->vm_start || address >= vma->vm_end)) {
-               /* page should be within any vma from prio_tree_next */
-               BUG_ON(!PageAnon(page));
+               /* page should be within @vma mapping range */
                return -EFAULT;
        }
        return address;
@@ -283,7 +283,10 @@ static int page_referenced_one(struct page *page,
        if (!pte)
                goto out;
 
-       if (ptep_clear_flush_young(vma, address, pte))
+       if (vma->vm_flags & VM_LOCKED) {
+               referenced++;
+               *mapcount = 1;  /* break early from loop */
+       } else if (ptep_clear_flush_young(vma, address, pte))
                referenced++;
 
        /* Pretend the page is referenced if the task has the
@@ -470,11 +473,12 @@ int page_mkclean(struct page *page)
 
        if (page_mapped(page)) {
                struct address_space *mapping = page_mapping(page);
-               if (mapping)
+               if (mapping) {
                        ret = page_mkclean_file(mapping, page);
-               if (page_test_dirty(page)) {
-                       page_clear_dirty(page);
-                       ret = 1;
+                       if (page_test_dirty(page)) {
+                               page_clear_dirty(page);
+                               ret = 1;
+                       }
                }
        }