fs/iomap: Fix buffered write page prefaulting
[linux-2.6-microblaze.git] / mm / memory.c
index 38d63f6..8f1de81 100644 (file)
@@ -439,6 +439,20 @@ void pmd_install(struct mm_struct *mm, pmd_t *pmd, pgtable_t *pte)
 
        if (likely(pmd_none(*pmd))) {   /* Has another populated it ? */
                mm_inc_nr_ptes(mm);
+               /*
+                * Ensure all pte setup (eg. pte page lock and page clearing) are
+                * visible before the pte is made visible to other CPUs by being
+                * put into page tables.
+                *
+                * The other side of the story is the pointer chasing in the page
+                * table walking code (when walking the page table without locking;
+                * ie. most of the time). Fortunately, these data accesses consist
+                * of a chain of data-dependent loads, meaning most CPUs (alpha
+                * being the notable exception) will already guarantee loads are
+                * seen in-order. See the alpha page table accessors for the
+                * smp_rmb() barriers in page table walking code.
+                */
+               smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */
                pmd_populate(mm, pmd, *pte);
                *pte = NULL;
        }
@@ -451,21 +465,6 @@ int __pte_alloc(struct mm_struct *mm, pmd_t *pmd)
        if (!new)
                return -ENOMEM;
 
-       /*
-        * Ensure all pte setup (eg. pte page lock and page clearing) are
-        * visible before the pte is made visible to other CPUs by being
-        * put into page tables.
-        *
-        * The other side of the story is the pointer chasing in the page
-        * table walking code (when walking the page table without locking;
-        * ie. most of the time). Fortunately, these data accesses consist
-        * of a chain of data-dependent loads, meaning most CPUs (alpha
-        * being the notable exception) will already guarantee loads are
-        * seen in-order. See the alpha page table accessors for the
-        * smp_rmb() barriers in page table walking code.
-        */
-       smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */
-
        pmd_install(mm, pmd, &new);
        if (new)
                pte_free(mm, new);
@@ -478,10 +477,9 @@ int __pte_alloc_kernel(pmd_t *pmd)
        if (!new)
                return -ENOMEM;
 
-       smp_wmb(); /* See comment in __pte_alloc */
-
        spin_lock(&init_mm.page_table_lock);
        if (likely(pmd_none(*pmd))) {   /* Has another populated it ? */
+               smp_wmb(); /* See comment in pmd_install() */
                pmd_populate_kernel(&init_mm, pmd, new);
                new = NULL;
        }
@@ -995,7 +993,7 @@ page_copy_prealloc(struct mm_struct *src_mm, struct vm_area_struct *vma,
        if (!new_page)
                return NULL;
 
-       if (mem_cgroup_charge(new_page, src_mm, GFP_KERNEL)) {
+       if (mem_cgroup_charge(page_folio(new_page), src_mm, GFP_KERNEL)) {
                put_page(new_page);
                return NULL;
        }
@@ -3007,7 +3005,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
                }
        }
 
-       if (mem_cgroup_charge(new_page, mm, GFP_KERNEL))
+       if (mem_cgroup_charge(page_folio(new_page), mm, GFP_KERNEL))
                goto oom_free_new;
        cgroup_throttle_swaprate(new_page, GFP_KERNEL);
 
@@ -3532,7 +3530,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
 
                                shadow = get_shadow_from_swap_cache(entry);
                                if (shadow)
-                                       workingset_refault(page, shadow);
+                                       workingset_refault(page_folio(page),
+                                                               shadow);
 
                                lru_cache_add(page);
 
@@ -3762,7 +3761,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
        if (!page)
                goto oom;
 
-       if (mem_cgroup_charge(page, vma->vm_mm, GFP_KERNEL))
+       if (mem_cgroup_charge(page_folio(page), vma->vm_mm, GFP_KERNEL))
                goto oom_free_page;
        cgroup_throttle_swaprate(page, GFP_KERNEL);
 
@@ -3845,7 +3844,6 @@ static vm_fault_t __do_fault(struct vm_fault *vmf)
                vmf->prealloc_pte = pte_alloc_one(vma->vm_mm);
                if (!vmf->prealloc_pte)
                        return VM_FAULT_OOM;
-               smp_wmb(); /* See comment in __pte_alloc() */
        }
 
        ret = vma->vm_ops->fault(vmf);
@@ -3916,7 +3914,6 @@ vm_fault_t do_set_pmd(struct vm_fault *vmf, struct page *page)
                vmf->prealloc_pte = pte_alloc_one(vma->vm_mm);
                if (!vmf->prealloc_pte)
                        return VM_FAULT_OOM;
-               smp_wmb(); /* See comment in __pte_alloc() */
        }
 
        vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);
@@ -4141,7 +4138,6 @@ static vm_fault_t do_fault_around(struct vm_fault *vmf)
                vmf->prealloc_pte = pte_alloc_one(vmf->vma->vm_mm);
                if (!vmf->prealloc_pte)
                        return VM_FAULT_OOM;
-               smp_wmb(); /* See comment in __pte_alloc() */
        }
 
        return vmf->vma->vm_ops->map_pages(vmf, start_pgoff, end_pgoff);
@@ -4188,7 +4184,8 @@ static vm_fault_t do_cow_fault(struct vm_fault *vmf)
        if (!vmf->cow_page)
                return VM_FAULT_OOM;
 
-       if (mem_cgroup_charge(vmf->cow_page, vma->vm_mm, GFP_KERNEL)) {
+       if (mem_cgroup_charge(page_folio(vmf->cow_page), vma->vm_mm,
+                               GFP_KERNEL)) {
                put_page(vmf->cow_page);
                return VM_FAULT_OOM;
        }
@@ -4253,7 +4250,7 @@ static vm_fault_t do_shared_fault(struct vm_fault *vmf)
  * We enter with non-exclusive mmap_lock (to exclude vma changes,
  * but allow concurrent faults).
  * The mmap_lock may have been released depending on flags and our
- * return value.  See filemap_fault() and __lock_page_or_retry().
+ * return value.  See filemap_fault() and __folio_lock_or_retry().
  * If mmap_lock is released, vma may become invalid (for example
  * by other thread calling munmap()).
  */
@@ -4494,7 +4491,7 @@ static vm_fault_t wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud)
  * concurrent faults).
  *
  * The mmap_lock may have been released depending on flags and our return value.
- * See filemap_fault() and __lock_page_or_retry().
+ * See filemap_fault() and __folio_lock_or_retry().
  */
 static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
 {
@@ -4598,7 +4595,7 @@ unlock:
  * By the time we get here, we already hold the mm semaphore
  *
  * The mmap_lock may have been released depending on flags and our
- * return value.  See filemap_fault() and __lock_page_or_retry().
+ * return value.  See filemap_fault() and __folio_lock_or_retry().
  */
 static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
                unsigned long address, unsigned int flags)
@@ -4754,7 +4751,7 @@ static inline void mm_account_fault(struct pt_regs *regs,
  * By the time we get here, we already hold the mm semaphore
  *
  * The mmap_lock may have been released depending on flags and our
- * return value.  See filemap_fault() and __lock_page_or_retry().
+ * return value.  See filemap_fault() and __folio_lock_or_retry().
  */
 vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
                           unsigned int flags, struct pt_regs *regs)
@@ -4815,13 +4812,13 @@ int __p4d_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
        if (!new)
                return -ENOMEM;
 
-       smp_wmb(); /* See comment in __pte_alloc */
-
        spin_lock(&mm->page_table_lock);
-       if (pgd_present(*pgd))          /* Another has populated it */
+       if (pgd_present(*pgd)) {        /* Another has populated it */
                p4d_free(mm, new);
-       else
+       } else {
+               smp_wmb(); /* See comment in pmd_install() */
                pgd_populate(mm, pgd, new);
+       }
        spin_unlock(&mm->page_table_lock);
        return 0;
 }
@@ -4838,11 +4835,10 @@ int __pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address)
        if (!new)
                return -ENOMEM;
 
-       smp_wmb(); /* See comment in __pte_alloc */
-
        spin_lock(&mm->page_table_lock);
        if (!p4d_present(*p4d)) {
                mm_inc_nr_puds(mm);
+               smp_wmb(); /* See comment in pmd_install() */
                p4d_populate(mm, p4d, new);
        } else  /* Another has populated it */
                pud_free(mm, new);
@@ -4863,14 +4859,14 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
        if (!new)
                return -ENOMEM;
 
-       smp_wmb(); /* See comment in __pte_alloc */
-
        ptl = pud_lock(mm, pud);
        if (!pud_present(*pud)) {
                mm_inc_nr_pmds(mm);
+               smp_wmb(); /* See comment in pmd_install() */
                pud_populate(mm, pud, new);
-       } else  /* Another has populated it */
+       } else {        /* Another has populated it */
                pmd_free(mm, new);
+       }
        spin_unlock(ptl);
        return 0;
 }
@@ -5251,7 +5247,7 @@ void __might_fault(const char *file, int line)
                return;
        if (pagefault_disabled())
                return;
-       __might_sleep(file, line, 0);
+       __might_sleep(file, line);
 #if defined(CONFIG_DEBUG_ATOMIC_SLEEP)
        if (current->mm)
                might_lock_read(&current->mm->mmap_lock);