perf cpumap: Add new map type for aggregation
[linux-2.6-microblaze.git] / mm / memory.c
index c48f8df..7d60876 100644 (file)
@@ -1171,6 +1171,15 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
                mmu_notifier_range_init(&range, MMU_NOTIFY_PROTECTION_PAGE,
                                        0, src_vma, src_mm, addr, end);
                mmu_notifier_invalidate_range_start(&range);
+               /*
+                * Disabling preemption is not needed for the write side, as
+                * the read side doesn't spin, but goes to the mmap_lock.
+                *
+                * Use the raw variant of the seqcount_t write API to avoid
+                * lockdep complaining about preemptibility.
+                */
+               mmap_assert_write_locked(src_mm);
+               raw_write_seqcount_begin(&src_mm->write_protect_seq);
        }
 
        ret = 0;
@@ -1187,8 +1196,10 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
                }
        } while (dst_pgd++, src_pgd++, addr = next, addr != end);
 
-       if (is_cow)
+       if (is_cow) {
+               raw_write_seqcount_end(&src_mm->write_protect_seq);
                mmu_notifier_invalidate_range_end(&range);
+       }
        return ret;
 }
 
@@ -4696,9 +4707,9 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
 }
 #endif /* __PAGETABLE_PMD_FOLDED */
 
-static int __follow_pte_pmd(struct mm_struct *mm, unsigned long address,
-                           struct mmu_notifier_range *range,
-                           pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp)
+int follow_pte(struct mm_struct *mm, unsigned long address,
+              struct mmu_notifier_range *range, pte_t **ptepp, pmd_t **pmdpp,
+              spinlock_t **ptlp)
 {
        pgd_t *pgd;
        p4d_t *p4d;
@@ -4763,32 +4774,6 @@ out:
        return -EINVAL;
 }
 
-static inline int follow_pte(struct mm_struct *mm, unsigned long address,
-                            pte_t **ptepp, spinlock_t **ptlp)
-{
-       int res;
-
-       /* (void) is needed to make gcc happy */
-       (void) __cond_lock(*ptlp,
-                          !(res = __follow_pte_pmd(mm, address, NULL,
-                                                   ptepp, NULL, ptlp)));
-       return res;
-}
-
-int follow_pte_pmd(struct mm_struct *mm, unsigned long address,
-                  struct mmu_notifier_range *range,
-                  pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp)
-{
-       int res;
-
-       /* (void) is needed to make gcc happy */
-       (void) __cond_lock(*ptlp,
-                          !(res = __follow_pte_pmd(mm, address, range,
-                                                   ptepp, pmdpp, ptlp)));
-       return res;
-}
-EXPORT_SYMBOL(follow_pte_pmd);
-
 /**
  * follow_pfn - look up PFN at a user virtual address
  * @vma: memory mapping
@@ -4809,7 +4794,7 @@ int follow_pfn(struct vm_area_struct *vma, unsigned long address,
        if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
                return ret;
 
-       ret = follow_pte(vma->vm_mm, address, &ptep, &ptl);
+       ret = follow_pte(vma->vm_mm, address, NULL, &ptep, NULL, &ptl);
        if (ret)
                return ret;
        *pfn = pte_pfn(*ptep);
@@ -4830,7 +4815,7 @@ int follow_phys(struct vm_area_struct *vma,
        if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
                goto out;
 
-       if (follow_pte(vma->vm_mm, address, &ptep, &ptl))
+       if (follow_pte(vma->vm_mm, address, NULL, &ptep, NULL, &ptl))
                goto out;
        pte = *ptep;
 
@@ -4874,11 +4859,10 @@ EXPORT_SYMBOL_GPL(generic_access_phys);
 #endif
 
 /*
- * Access another process' address space as given in mm.  If non-NULL, use the
- * given task for page fault accounting.
+ * Access another process' address space as given in mm.
  */
-int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
-               unsigned long addr, void *buf, int len, unsigned int gup_flags)
+int __access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf,
+                      int len, unsigned int gup_flags)
 {
        struct vm_area_struct *vma;
        void *old_buf = buf;
@@ -4955,7 +4939,7 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
 int access_remote_vm(struct mm_struct *mm, unsigned long addr,
                void *buf, int len, unsigned int gup_flags)
 {
-       return __access_remote_vm(NULL, mm, addr, buf, len, gup_flags);
+       return __access_remote_vm(mm, addr, buf, len, gup_flags);
 }
 
 /*
@@ -4973,7 +4957,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr,
        if (!mm)
                return 0;
 
-       ret = __access_remote_vm(tsk, mm, addr, buf, len, gup_flags);
+       ret = __access_remote_vm(mm, addr, buf, len, gup_flags);
 
        mmput(mm);