The prot_numa_skip() checks should be suitable for pmd folio too, which helps to avoid unnecessary pmd change and folio migration attempts. Signed-off-by: Kefeng Wang --- mm/huge_memory.c | 21 +++++++-------------- mm/internal.h | 2 ++ mm/mprotect.c | 2 +- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 1b81680b4225..feca5a19104a 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2395,8 +2395,7 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, #endif if (prot_numa) { - struct folio *folio; - bool toptier; + int target_node = NUMA_NO_NODE; /* * Avoid trapping faults against the zero page. The read-only * data is likely to be read-cached on the local CPU and @@ -2408,19 +2407,13 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, if (pmd_protnone(*pmd)) goto unlock; - folio = pmd_folio(*pmd); - toptier = node_is_toptier(folio_nid(folio)); - /* - * Skip scanning top tier node if normal numa - * balancing is disabled - */ - if (!(sysctl_numa_balancing_mode & NUMA_BALANCING_NORMAL) && - toptier) - goto unlock; + /* Get target node for single threaded private VMAs */ + if (!(vma->vm_flags & VM_SHARED) && + atomic_read(&vma->vm_mm->mm_users) == 1) + target_node = numa_node_id(); - if (folio_use_access_time(folio)) - folio_xchg_access_time(folio, - jiffies_to_msecs(jiffies)); + if (prot_numa_skip(vma, target_node, pmd_folio(*pmd))) + goto unlock; } /* * In case prot_numa, we are under mmap_read_lock(mm). It's critical diff --git a/mm/internal.h b/mm/internal.h index 1561fc2ff5b8..65148cb98b9c 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1378,6 +1378,8 @@ void vunmap_range_noflush(unsigned long start, unsigned long end); void __vunmap_range_noflush(unsigned long start, unsigned long end); +bool prot_numa_skip(struct vm_area_struct *vma, int target_node, + struct folio *folio); int numa_migrate_check(struct folio *folio, struct vm_fault *vmf, unsigned long addr, int *flags, bool writable, int *last_cpupid); diff --git a/mm/mprotect.c b/mm/mprotect.c index 0f31c09c1726..026e7c7fa111 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -118,7 +118,7 @@ static int mprotect_folio_pte_batch(struct folio *folio, pte_t *ptep, return folio_pte_batch_flags(folio, NULL, ptep, &pte, max_nr_ptes, flags); } -static bool prot_numa_skip(struct vm_area_struct *vma, int target_node, +bool prot_numa_skip(struct vm_area_struct *vma, int target_node, struct folio *folio) { bool ret = true; -- 2.43.0