]> Git Repo - linux.git/blobdiff - mm/memory.c
mm/mmu_notifier: remove unused mmu_notifier_range_update_to_read_only export
[linux.git] / mm / memory.c
index aad226daf41bd5de81b2ea55c39443e8774b4091..c6bacd58d032a1028eef949ae32a826c4930a371 100644 (file)
@@ -625,6 +625,16 @@ out:
        return pfn_to_page(pfn);
 }
 
+struct folio *vm_normal_folio(struct vm_area_struct *vma, unsigned long addr,
+                           pte_t pte)
+{
+       struct page *page = vm_normal_page(vma, addr, pte);
+
+       if (page)
+               return page_folio(page);
+       return NULL;
+}
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
                                pmd_t pmd)
@@ -828,12 +838,8 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
                        return -EBUSY;
                return -ENOENT;
        } else if (is_pte_marker_entry(entry)) {
-               /*
-                * We're copying the pgtable should only because dst_vma has
-                * uffd-wp enabled, do sanity check.
-                */
-               WARN_ON_ONCE(!userfaultfd_wp(dst_vma));
-               set_pte_at(dst_mm, addr, dst_pte, pte);
+               if (is_swapin_error_entry(entry) || userfaultfd_wp(dst_vma))
+                       set_pte_at(dst_mm, addr, dst_pte, pte);
                return 0;
        }
        if (!userfaultfd_wp(dst_vma))
@@ -882,7 +888,7 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma
        pte = maybe_mkwrite(pte_mkdirty(pte), dst_vma);
        if (userfaultfd_pte_wp(dst_vma, *src_pte))
                /* Uffd-wp needs to be delivered to dest pte as well */
-               pte = pte_wrprotect(pte_mkuffd_wp(pte));
+               pte = pte_mkuffd_wp(pte);
        set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte);
        return 0;
 }
@@ -1260,7 +1266,7 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
 
        if (is_cow) {
                mmu_notifier_range_init(&range, MMU_NOTIFY_PROTECTION_PAGE,
-                                       0, src_vma, src_mm, addr, end);
+                                       0, src_mm, addr, end);
                mmu_notifier_invalidate_range_start(&range);
                /*
                 * Disabling preemption is not needed for the write side, as
@@ -1396,8 +1402,7 @@ again:
                                                force_flush = 1;
                                        }
                                }
-                               if (pte_young(ptent) &&
-                                   likely(!(vma->vm_flags & VM_SEQ_READ)))
+                               if (pte_young(ptent) && likely(vma_has_recency(vma)))
                                        mark_page_accessed(page);
                        }
                        rss[mm_counter(page)]--;
@@ -1678,7 +1683,7 @@ void unmap_vmas(struct mmu_gather *tlb, struct maple_tree *mt,
        };
        MA_STATE(mas, mt, vma->vm_end, vma->vm_end);
 
-       mmu_notifier_range_init(&range, MMU_NOTIFY_UNMAP, 0, vma, vma->vm_mm,
+       mmu_notifier_range_init(&range, MMU_NOTIFY_UNMAP, 0, vma->vm_mm,
                                start_addr, end_addr);
        mmu_notifier_invalidate_range_start(&range);
        do {
@@ -1687,36 +1692,6 @@ void unmap_vmas(struct mmu_gather *tlb, struct maple_tree *mt,
        mmu_notifier_invalidate_range_end(&range);
 }
 
-/**
- * zap_page_range - remove user pages in a given range
- * @vma: vm_area_struct holding the applicable pages
- * @start: starting address of pages to zap
- * @size: number of bytes to zap
- *
- * Caller must protect the VMA list
- */
-void zap_page_range(struct vm_area_struct *vma, unsigned long start,
-               unsigned long size)
-{
-       struct maple_tree *mt = &vma->vm_mm->mm_mt;
-       unsigned long end = start + size;
-       struct mmu_notifier_range range;
-       struct mmu_gather tlb;
-       MA_STATE(mas, mt, vma->vm_end, vma->vm_end);
-
-       lru_add_drain();
-       mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, vma->vm_mm,
-                               start, start + size);
-       tlb_gather_mmu(&tlb, vma->vm_mm);
-       update_hiwater_rss(vma->vm_mm);
-       mmu_notifier_invalidate_range_start(&range);
-       do {
-               unmap_single_vma(&tlb, vma, start, range.end, NULL);
-       } while ((vma = mas_find(&mas, end - 1)) != NULL);
-       mmu_notifier_invalidate_range_end(&range);
-       tlb_finish_mmu(&tlb);
-}
-
 /**
  * zap_page_range_single - remove user pages in a given range
  * @vma: vm_area_struct holding the applicable pages
@@ -1734,7 +1709,7 @@ void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
        struct mmu_gather tlb;
 
        lru_add_drain();
-       mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, vma->vm_mm,
+       mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm,
                                address, end);
        if (is_vm_hugetlb_page(vma))
                adjust_range_if_pmd_sharing_possible(vma, &range.start,
@@ -3116,7 +3091,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
 
        __SetPageUptodate(new_page);
 
-       mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, mm,
+       mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm,
                                vmf->address & PAGE_MASK,
                                (vmf->address & PAGE_MASK) + PAGE_SIZE);
        mmu_notifier_invalidate_range_start(&range);
@@ -3586,7 +3561,7 @@ static vm_fault_t remove_device_exclusive_entry(struct vm_fault *vmf)
 
        if (!folio_lock_or_retry(folio, vma->vm_mm, vmf->flags))
                return VM_FAULT_RETRY;
-       mmu_notifier_range_init_owner(&range, MMU_NOTIFY_EXCLUSIVE, 0, vma,
+       mmu_notifier_range_init_owner(&range, MMU_NOTIFY_EXCLUSIVE, 0,
                                vma->vm_mm, vmf->address & PAGE_MASK,
                                (vmf->address & PAGE_MASK) + PAGE_SIZE, NULL);
        mmu_notifier_invalidate_range_start(&range);
@@ -3629,8 +3604,12 @@ static vm_fault_t pte_marker_clear(struct vm_fault *vmf)
        /*
         * Be careful so that we will only recover a special uffd-wp pte into a
         * none pte.  Otherwise it means the pte could have changed, so retry.
+        *
+        * This should also cover the case where e.g. the pte changed
+        * quickly from a PTE_MARKER_UFFD_WP into PTE_MARKER_SWAPIN_ERROR.
+        * So is_pte_marker() check is not enough to safely drop the pte.
         */
-       if (is_pte_marker(*vmf->pte))
+       if (pte_same(vmf->orig_pte, *vmf->pte))
                pte_clear(vmf->vma->vm_mm, vmf->address, vmf->pte);
        pte_unmap_unlock(vmf->pte, vmf->ptl);
        return 0;
@@ -3950,10 +3929,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
        flush_icache_page(vma, page);
        if (pte_swp_soft_dirty(vmf->orig_pte))
                pte = pte_mksoft_dirty(pte);
-       if (pte_swp_uffd_wp(vmf->orig_pte)) {
+       if (pte_swp_uffd_wp(vmf->orig_pte))
                pte = pte_mkuffd_wp(pte);
-               pte = pte_wrprotect(pte);
-       }
        vmf->orig_pte = pte;
 
        /* ksm created a completely new copy */
@@ -4296,7 +4273,7 @@ void do_set_pte(struct vm_fault *vmf, struct page *page, unsigned long addr)
        if (write)
                entry = maybe_mkwrite(pte_mkdirty(entry), vma);
        if (unlikely(uffd_wp))
-               entry = pte_mkuffd_wp(pte_wrprotect(entry));
+               entry = pte_mkuffd_wp(entry);
        /* copy-on-write page */
        if (write && !(vma->vm_flags & VM_SHARED)) {
                inc_mm_counter(vma->vm_mm, MM_ANONPAGES);
@@ -5137,8 +5114,8 @@ static inline void mm_account_fault(struct pt_regs *regs,
 #ifdef CONFIG_LRU_GEN
 static void lru_gen_enter_fault(struct vm_area_struct *vma)
 {
-       /* the LRU algorithm doesn't apply to sequential or random reads */
-       current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ));
+       /* the LRU algorithm only applies to accesses with recency */
+       current->in_lru_fault = vma_has_recency(vma);
 }
 
 static void lru_gen_exit_fault(void)
This page took 0.038846 seconds and 4 git commands to generate.