mm/vmalloc: fallback to a single page allocator
[linux-2.6-microblaze.git] / mm / memory.c
index 486f4a2..3dd6b2e 100644 (file)
@@ -3023,6 +3023,8 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
                                munlock_vma_page(old_page);
                        unlock_page(old_page);
                }
+               if (page_copied)
+                       free_swap_cache(old_page);
                put_page(old_page);
        }
        return page_copied ? VM_FAULT_WRITE : 0;
@@ -3047,7 +3049,7 @@ oom:
  * The function expects the page to be locked or other protection against
  * concurrent faults / writeback (such as DAX radix tree locks).
  *
- * Return: %VM_FAULT_WRITE on success, %0 when PTE got changed before
+ * Return: %0 on success, %VM_FAULT_NOPAGE when PTE got changed before
  * we acquired PTE lock.
  */
 vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf)
@@ -3353,6 +3355,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct page *page = NULL, *swapcache;
+       struct swap_info_struct *si = NULL;
        swp_entry_t entry;
        pte_t pte;
        int locked;
@@ -3380,14 +3383,16 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
                goto out;
        }
 
+       /* Prevent swapoff from happening to us. */
+       si = get_swap_device(entry);
+       if (unlikely(!si))
+               goto out;
 
        delayacct_set_flag(current, DELAYACCT_PF_SWAPIN);
        page = lookup_swap_cache(entry, vma, vmf->address);
        swapcache = page;
 
        if (!page) {
-               struct swap_info_struct *si = swp_swap_info(entry);
-
                if (data_race(si->flags & SWP_SYNCHRONOUS_IO) &&
                    __swap_count(entry) == 1) {
                        /* skip swapcache */
@@ -3556,6 +3561,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 unlock:
        pte_unmap_unlock(vmf->pte, vmf->ptl);
 out:
+       if (si)
+               put_swap_device(si);
        return ret;
 out_nomap:
        pte_unmap_unlock(vmf->pte, vmf->ptl);
@@ -3567,6 +3574,8 @@ out_release:
                unlock_page(swapcache);
                put_page(swapcache);
        }
+       if (si)
+               put_swap_device(si);
        return ret;
 }
 
@@ -4985,8 +4994,8 @@ int __access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf,
                         * Check if this is a VM_IO | VM_PFNMAP VMA, which
                         * we can access using slightly different code.
                         */
-                       vma = find_vma(mm, addr);
-                       if (!vma || vma->vm_start > addr)
+                       vma = vma_lookup(mm, addr);
+                       if (!vma)
                                break;
                        if (vma->vm_ops && vma->vm_ops->access)
                                ret = vma->vm_ops->access(vma, addr, buf,