# Re: \[PATCH 09/13\] fs/proc/task\_mmu: convert VMA flag tests to use vma\_flags\_t

- From: Lorenzo Stoakes (ARM) \<ljs@kernel.org\>
- Date: 2026-11-06 10:46:49 
- List: linuxppc-dev
- Page: https://ratatoskr.run/linuxppc-dev/2026/11/17877399
- Thread: https://ratatoskr.run/linux-mm/2026/11/17874173/t.md

```text
On Fri, Nov 06, 2026 at 02:59:25PM +0800, Lance Yang wrote:
>
> On Thu, Nov 05, 2026 at 09:31:00PM +0000, Lorenzo Stoakes (ARM) wrote:
> >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) <ljs@kernel.org>
> >---
> > 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);
>
> vm_flags_clear() still warns on VM_SOFTDIRTY when pgtable_supports_soft_dirty()
> is false. Did you mean to drop that?

Yep it's silly. Checking every single operation with VMA_SOFTDIRTY_BIT for
whether CONFIG_MEM_SOFT_DIRTY is enabled, which is not done for literally any
other VMA flag, is ludicrous frankly :)

>
> (Vaguely recall you weren't too keen on that warn, though I could be wrong.)
>
> Otherwise, LGTM!
>
> Reviewed-by: Lance Yang <lance.yang@linux.dev>

Thanks!

--
Cheers, Lorenzo

```
