Replace use of the legacy vm_flags_t flags with vma_flags_t values where VMA flags are tested directly in /proc/$pid/[s]maps, pagemap, clear_refs and PROCMAP_QUERY. In replacing vm_flags_clear() (which takes the VMA write lock) with vma_clear_flags() (which does not) in clear_refs_write(), we explicitly write lock the VMA. The mmap write lock is already held at this point. The show_vma_header_prefix() and show_smap_vma_flags() output functions and the thp_vma_allowable_orders() call continue to use legacy flags for the time being. No functional change intended. Signed-off-by: Lorenzo Stoakes (ARM) --- fs/proc/task_mmu.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 22361607020d..b6e8ef15e40e 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -569,18 +569,18 @@ static struct vm_area_struct *query_matching_vma(struct proc_maps_locking_ctx *l /* VMA permissions should satisfy query flags */ if (flags & PROCMAP_QUERY_VMA_FLAGS) { - u32 perm = 0; + vma_flags_t perm = EMPTY_VMA_FLAGS; if (flags & PROCMAP_QUERY_VMA_READABLE) - perm |= VM_READ; + vma_flags_set(&perm, VMA_READ_BIT); if (flags & PROCMAP_QUERY_VMA_WRITABLE) - perm |= VM_WRITE; + vma_flags_set(&perm, VMA_WRITE_BIT); if (flags & PROCMAP_QUERY_VMA_EXECUTABLE) - perm |= VM_EXEC; + vma_flags_set(&perm, VMA_EXEC_BIT); if (flags & PROCMAP_QUERY_VMA_SHARED) - perm |= VM_MAYSHARE; + vma_flags_set(&perm, VMA_MAYSHARE_BIT); - if ((vma->vm_flags & perm) != perm) + if (!vma_test_all_mask(vma, perm)) goto skip_vma; } @@ -647,13 +647,13 @@ static int do_procmap_query(struct mm_struct *mm, void __user *uarg) karg.vma_end = vma->vm_end; karg.vma_flags = 0; - if (vma->vm_flags & VM_READ) + if (vma_test(vma, VMA_READ_BIT)) karg.vma_flags |= PROCMAP_QUERY_VMA_READABLE; - if (vma->vm_flags & VM_WRITE) + if (vma_test(vma, VMA_WRITE_BIT)) karg.vma_flags |= PROCMAP_QUERY_VMA_WRITABLE; - if (vma->vm_flags & VM_EXEC) + if (vma_test(vma, VMA_EXEC_BIT)) karg.vma_flags |= PROCMAP_QUERY_VMA_EXECUTABLE; - if (vma->vm_flags & VM_MAYSHARE) + if (vma_test(vma, VMA_MAYSHARE_BIT)) karg.vma_flags |= PROCMAP_QUERY_VMA_SHARED; karg.vma_page_size = vma_kernel_pagesize(vma); @@ -970,7 +970,7 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr, { struct mem_size_stats *mss = walk->private; struct vm_area_struct *vma = walk->vma; - bool locked = !!(vma->vm_flags & VM_LOCKED); + bool locked = vma_test(vma, VMA_LOCKED_BIT); struct page *page = NULL; bool present = false, young = false, dirty = false; pte_t ptent = ptep_get(pte); @@ -1017,7 +1017,7 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr, { struct mem_size_stats *mss = walk->private; struct vm_area_struct *vma = walk->vma; - bool locked = !!(vma->vm_flags & VM_LOCKED); + bool locked = vma_test(vma, VMA_LOCKED_BIT); struct page *page = NULL; bool present = false; struct folio *folio; @@ -1728,7 +1728,7 @@ static int clear_refs_test_walk(unsigned long start, unsigned long end, struct clear_refs_private *cp = walk->private; struct vm_area_struct *vma = walk->vma; - if (vma->vm_flags & VM_PFNMAP) + if (vma_test(vma, VMA_PFNMAP_BIT)) return 1; /* @@ -1798,9 +1798,10 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, if (type == CLEAR_REFS_SOFT_DIRTY) { for_each_vma(vmi, vma) { - if (!(vma->vm_flags & VM_SOFTDIRTY)) + if (!vma_test(vma, VMA_SOFTDIRTY_BIT)) continue; - vm_flags_clear(vma, VM_SOFTDIRTY); + vma_start_write(vma); + vma_clear_flags(vma, VMA_SOFTDIRTY_BIT); vma_set_page_prot(vma); } @@ -1904,7 +1905,7 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end, break; /* Addresses in the VMA. */ - if (vma->vm_flags & VM_SOFTDIRTY) + if (vma_test(vma, VMA_SOFTDIRTY_BIT)) pme = make_pme(0, PM_SOFT_DIRTY); for (; addr < min(end, vma->vm_end); addr += PAGE_SIZE) { err = add_to_pagemap(&pme, pm); @@ -1976,7 +1977,7 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm, } out: - if (vma->vm_flags & VM_SOFTDIRTY) + if (vma_test(vma, VMA_SOFTDIRTY_BIT)) flags |= PM_SOFT_DIRTY; return make_pme(frame, flags); @@ -1994,7 +1995,7 @@ static int pagemap_pmd_range_thp(pmd_t *pmdp, unsigned long addr, struct folio *folio = NULL; int err = 0; - if (vma->vm_flags & VM_SOFTDIRTY) + if (vma_test(vma, VMA_SOFTDIRTY_BIT)) flags |= PM_SOFT_DIRTY; if (pmd_none(pmd)) @@ -2116,7 +2117,7 @@ static int pagemap_hugetlb_range(pte_t *ptep, unsigned long hmask, int err = 0; pte_t pte; - if (vma->vm_flags & VM_SOFTDIRTY) + if (vma_test(vma, VMA_SOFTDIRTY_BIT)) flags |= PM_SOFT_DIRTY; ptl = huge_pte_lock(hstate_vma(vma), walk->mm, ptep); @@ -2625,13 +2626,13 @@ static int pagemap_scan_test_walk(unsigned long start, unsigned long end, */ } - if (vma->vm_flags & VM_PFNMAP) + if (vma_test(vma, VMA_PFNMAP_BIT)) return 1; if (wp_allowed) vma_category |= PAGE_IS_WPALLOWED; - if (vma->vm_flags & VM_SOFTDIRTY) + if (vma_test(vma, VMA_SOFTDIRTY_BIT)) vma_category |= PAGE_IS_SOFT_DIRTY; if (!pagemap_scan_is_interesting_vma(vma_category, p)) -- 2.56.0