[PATCH RESEND 00/12] mm: add bitmap VMA flag helpers and convert all mmap_prepare to use them

Lorenzo Stoakes posted 12 patches 2 weeks, 4 days ago
There is a newer version of this series
arch/x86/kernel/cpu/sgx/ioctl.c            |    2 +-
drivers/char/mem.c                         |    6 +-
drivers/dax/device.c                       |   10 +-
drivers/gpu/drm/drm_gem.c                  |    5 +-
drivers/gpu/drm/i915/gem/i915_gem_shmem.c  |    2 +-
drivers/gpu/drm/i915/gem/i915_gem_ttm.c    |    3 +-
drivers/gpu/drm/i915/gt/shmem_utils.c      |    3 +-
drivers/gpu/drm/ttm/tests/ttm_tt_test.c    |    2 +-
drivers/gpu/drm/ttm/ttm_backup.c           |    3 +-
drivers/gpu/drm/ttm/ttm_tt.c               |    2 +-
fs/aio.c                                   |    2 +-
fs/erofs/data.c                            |    5 +-
fs/ext4/file.c                             |    4 +-
fs/hugetlbfs/inode.c                       |   14 +-
fs/ntfs3/file.c                            |    2 +-
fs/orangefs/file.c                         |    4 +-
fs/ramfs/file-nommu.c                      |    2 +-
fs/resctrl/pseudo_lock.c                   |    2 +-
fs/romfs/mmap-nommu.c                      |    2 +-
fs/xfs/scrub/xfile.c                       |    3 +-
fs/xfs/xfs_buf_mem.c                       |    2 +-
fs/xfs/xfs_file.c                          |    4 +-
fs/zonefs/file.c                           |    3 +-
include/linux/dax.h                        |    4 +-
include/linux/hugetlb.h                    |    6 +-
include/linux/hugetlb_inline.h             |   10 +
include/linux/mm.h                         |  244 ++-
include/linux/mm_types.h                   |    9 +-
include/linux/shmem_fs.h                   |    8 +-
ipc/shm.c                                  |   12 +-
kernel/relay.c                             |    2 +-
mm/filemap.c                               |    2 +-
mm/hugetlb.c                               |   22 +-
mm/internal.h                              |    2 +-
mm/khugepaged.c                            |    2 +-
mm/madvise.c                               |    2 +-
mm/memfd.c                                 |    6 +-
mm/memory.c                                |   17 +-
mm/mmap.c                                  |   10 +-
mm/mremap.c                                |    2 +-
mm/secretmem.c                             |    7 +-
mm/shmem.c                                 |   59 +-
mm/util.c                                  |    2 +-
mm/vma.c                                   |   13 +-
mm/vma.h                                   |    3 +-
security/keys/big_key.c                    |    2 +-
tools/include/linux/bitmap.h               |   22 +
tools/lib/bitmap.c                         |   29 +
tools/testing/vma/Makefile                 |    7 +-
tools/testing/vma/include/custom.h         |  119 ++
tools/testing/vma/include/dup.h            | 1332 ++++++++++++++
tools/testing/vma/include/stubs.h          |  428 +++++
tools/testing/vma/main.c                   |   55 +
tools/testing/vma/shared.c                 |  131 ++
tools/testing/vma/shared.h                 |  114 ++
tools/testing/vma/{vma.c => tests/merge.c} |  332 +---
tools/testing/vma/tests/mmap.c             |   57 +
tools/testing/vma/tests/vma.c              |  339 ++++
tools/testing/vma/vma_internal.h           | 1847 +-------------------
59 files changed, 3042 insertions(+), 2303 deletions(-)
create mode 100644 tools/testing/vma/include/custom.h
create mode 100644 tools/testing/vma/include/dup.h
create mode 100644 tools/testing/vma/include/stubs.h
create mode 100644 tools/testing/vma/main.c
create mode 100644 tools/testing/vma/shared.c
create mode 100644 tools/testing/vma/shared.h
rename tools/testing/vma/{vma.c => tests/merge.c} (82%)
create mode 100644 tools/testing/vma/tests/mmap.c
create mode 100644 tools/testing/vma/tests/vma.c
[PATCH RESEND 00/12] mm: add bitmap VMA flag helpers and convert all mmap_prepare to use them
Posted by Lorenzo Stoakes 2 weeks, 4 days ago
We introduced the bitmap VMA type vma_flags_t in the aptly named commit
9ea35a25d51b ("mm: introduce VMA flags bitmap type") in order to permit
future growth in VMA flags and to prevent the asinine requirement that VMA
flags be available to 64-bit kernels only if they happened to use a bit
number about 32-bits.

This is a long-term project as there are very many users of VMA flags
within the kernel that need to be updated in order to utilise this new
type.

In order to further this aim, this series adds a number of helper functions
to enable ordinary interactions with VMA flags - that is testing, setting
and clearing them.

In order to make working with VMA bit numbers less cumbersome this series
introduces the mk_vma_flags() helper macro which generates a vma_flags_t
from a variadic parameter list, e.g.:

	vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
					 VMA_EXEC_BIT);

It turns out that the compiler optimises this very well to the point that
this is just as efficient as using VM_xxx pre-computed bitmap values.

This series then introduces the following functions:

	bool vma_flags_test_mask(vma_flags_t flags, vma_flags_t to_test);
	bool vma_flags_test_all_mask(vma_flags_t flags, vma_flags_t to_test);
	void vma_flags_set_mask(vma_flags_t *flags, vma_flags_t to_set);
	void vma_flags_clear_mask(vma_flags_t *flags, vma_flags_t to_clear);

Providing means of testing any flag, testing all flags, setting, and clearing a
specific vma_flags_t mask.

For convenience, helper macros are provided - vma_flags_test(),
vma_flags_set() and vma_flags_clear(), each of which utilise mk_vma_flags()
to make these operations easier, as well as an EMPTY_VMA_FLAGS macro to
make initialisation of an empty vma_flags_t value easier, e.g.:

	vma_flags_t flags = EMPTY_VMA_FLAGS;

	vma_flags_set(&flags, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
	...
	if (vma_flags_test(flags, VMA_READ_BIT)) {
		...
	}
	...
	if (vma_flags_test_all_mask(flags, VMA_REMAP_FLAGS)) {
		...
	}
	...
	vma_flags_clear(&flags, VMA_READ_BIT);

Since callers are often dealing with a vm_area_struct (VMA) or vm_area_desc
(VMA descriptor as used in .mmap_prepare) object, this series further
provides helpers for these - firstly vma_set_flags_mask() and vma_set_flags() for a
VMA:

	vma_flags_t flags = EMPTY_VMA_FLAGS:

	vma_flags_set(&flags, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
	...
	vma_set_flags_mask(&vma, flags);
	...
	vma_set_flags(&vma, VMA_DONTDUMP_BIT);

Note that these do NOT ensure appropriate locks are taken and assume the
callers takes care of this.

For VMA descriptors this series adds vma_desc_[test, set,
clear]_flags_mask() and vma_desc_[test, set, clear]_flags() for a VMA
descriptor, e.g.:

	static int foo_mmap_prepare(struct vm_area_desc *desc)
	{
		...
		vma_desc_set_flags(desc, VMA_SEQ_READ_BIT);
		vma_desc_clear_flags(desc, VMA_RAND_READ_BIT);
		...
		if (vma_desc_test_flags(desc, VMA_SHARED_BIT) {
			...
		}
		...
	}

With these helpers introduced, this series then updates all mmap_prepare
users to make use of the vma_flags_t vm_area_desc->vma_flags field rather
than the legacy vm_flags_t vm_area_desc->vm_flags field.

In order to do so, several other related functions need to be updated, with
separate patches for larger changes in hugetlbfs, secretmem and shmem
before finally removing vm_area_desc->vm_flags altogether.

This lays the foundations for future elimination of vm_flags_t and
associated defines and functionality altogether in the long run, and
elimination of the use of vm_flags_t in f_op->mmap() hooks in the near term
as mmap_prepare replaces these.

There is a useful synergy between the VMA flags and mmap_prepare work here
as with this change in place, converting f_op->mmap() to f_op->mmap_prepare
naturally also converts use of vm_flags_t to vma_flags_t in all drivers
which declare mmap handlers.

This accounts for the majority of the users of the legacy vm_flags_*()
helpers and thus a large number of drivers which need to interact with VMA
flags in general.

This series also updates the userland VMA tests to account for the change,
and adds unit tests for these helper functions to assert that they behave
as expected.

In order to faciliate this change in a sensible way, the series also
separates out the VMA unit tests into - code that is duplicated from the
kernel that should be kept in sync, code that is customised for test
purposes and code that is stubbed out.

We also separate out the VMA userland tests into separate files to make it
easier to manage and to provide a sensible baseline for adding the userland
tests for these helpers.


v1 resend:
* Rebased on mm-unstable to fix vma_internal.h conflict tested and confirmed
  working.

v1:
https://lore.kernel.org/all/cover.1768834061.git.lorenzo.stoakes@oracle.com/

Lorenzo Stoakes (12):
  mm: rename vma_flag_test/set_atomic() to vma_test/set_atomic_flag()
  mm: add mk_vma_flags() bitmap flag macro helper
  tools: bitmap: add missing bitmap_[subset(), andnot()]
  mm: add basic VMA flag operation helper functions
  mm: update hugetlbfs to use VMA flags on mmap_prepare
  mm: update secretmem to use VMA flags on mmap_prepare
  mm: update shmem_[kernel]_file_*() functions to use vma_flags_t
  mm: update all remaining mmap_prepare users to use vma_flags_t
  mm: make vm_area_desc utilise vma_flags_t only
  tools/testing/vma: separate VMA userland tests into separate files
  tools/testing/vma: separate out vma_internal.h into logical headers
  tools/testing/vma: add VMA userland tests for VMA flag functions

 arch/x86/kernel/cpu/sgx/ioctl.c            |    2 +-
 drivers/char/mem.c                         |    6 +-
 drivers/dax/device.c                       |   10 +-
 drivers/gpu/drm/drm_gem.c                  |    5 +-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c  |    2 +-
 drivers/gpu/drm/i915/gem/i915_gem_ttm.c    |    3 +-
 drivers/gpu/drm/i915/gt/shmem_utils.c      |    3 +-
 drivers/gpu/drm/ttm/tests/ttm_tt_test.c    |    2 +-
 drivers/gpu/drm/ttm/ttm_backup.c           |    3 +-
 drivers/gpu/drm/ttm/ttm_tt.c               |    2 +-
 fs/aio.c                                   |    2 +-
 fs/erofs/data.c                            |    5 +-
 fs/ext4/file.c                             |    4 +-
 fs/hugetlbfs/inode.c                       |   14 +-
 fs/ntfs3/file.c                            |    2 +-
 fs/orangefs/file.c                         |    4 +-
 fs/ramfs/file-nommu.c                      |    2 +-
 fs/resctrl/pseudo_lock.c                   |    2 +-
 fs/romfs/mmap-nommu.c                      |    2 +-
 fs/xfs/scrub/xfile.c                       |    3 +-
 fs/xfs/xfs_buf_mem.c                       |    2 +-
 fs/xfs/xfs_file.c                          |    4 +-
 fs/zonefs/file.c                           |    3 +-
 include/linux/dax.h                        |    4 +-
 include/linux/hugetlb.h                    |    6 +-
 include/linux/hugetlb_inline.h             |   10 +
 include/linux/mm.h                         |  244 ++-
 include/linux/mm_types.h                   |    9 +-
 include/linux/shmem_fs.h                   |    8 +-
 ipc/shm.c                                  |   12 +-
 kernel/relay.c                             |    2 +-
 mm/filemap.c                               |    2 +-
 mm/hugetlb.c                               |   22 +-
 mm/internal.h                              |    2 +-
 mm/khugepaged.c                            |    2 +-
 mm/madvise.c                               |    2 +-
 mm/memfd.c                                 |    6 +-
 mm/memory.c                                |   17 +-
 mm/mmap.c                                  |   10 +-
 mm/mremap.c                                |    2 +-
 mm/secretmem.c                             |    7 +-
 mm/shmem.c                                 |   59 +-
 mm/util.c                                  |    2 +-
 mm/vma.c                                   |   13 +-
 mm/vma.h                                   |    3 +-
 security/keys/big_key.c                    |    2 +-
 tools/include/linux/bitmap.h               |   22 +
 tools/lib/bitmap.c                         |   29 +
 tools/testing/vma/Makefile                 |    7 +-
 tools/testing/vma/include/custom.h         |  119 ++
 tools/testing/vma/include/dup.h            | 1332 ++++++++++++++
 tools/testing/vma/include/stubs.h          |  428 +++++
 tools/testing/vma/main.c                   |   55 +
 tools/testing/vma/shared.c                 |  131 ++
 tools/testing/vma/shared.h                 |  114 ++
 tools/testing/vma/{vma.c => tests/merge.c} |  332 +---
 tools/testing/vma/tests/mmap.c             |   57 +
 tools/testing/vma/tests/vma.c              |  339 ++++
 tools/testing/vma/vma_internal.h           | 1847 +-------------------
 59 files changed, 3042 insertions(+), 2303 deletions(-)
 create mode 100644 tools/testing/vma/include/custom.h
 create mode 100644 tools/testing/vma/include/dup.h
 create mode 100644 tools/testing/vma/include/stubs.h
 create mode 100644 tools/testing/vma/main.c
 create mode 100644 tools/testing/vma/shared.c
 create mode 100644 tools/testing/vma/shared.h
 rename tools/testing/vma/{vma.c => tests/merge.c} (82%)
 create mode 100644 tools/testing/vma/tests/mmap.c
 create mode 100644 tools/testing/vma/tests/vma.c

--
2.52.0
Re: [PATCH RESEND 00/12] mm: add bitmap VMA flag helpers and convert all mmap_prepare to use them
Posted by Andrew Morton 2 weeks, 4 days ago
On Mon, 19 Jan 2026 21:19:02 +0000 Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:

> We introduced the bitmap VMA type vma_flags_t in the aptly named commit
> 9ea35a25d51b ("mm: introduce VMA flags bitmap type") in order to permit
> future growth in VMA flags and to prevent the asinine requirement that VMA
> flags be available to 64-bit kernels only if they happened to use a bit
> number about 32-bits.
> 
> This is a long-term project as there are very many users of VMA flags
> within the kernel that need to be updated in order to utilise this new
> type.

Thanks, I added this to mm.git's mm-new branch for some public exposure.

I suppressed the usual email storm.
Re: [PATCH RESEND 00/12] mm: add bitmap VMA flag helpers and convert all mmap_prepare to use them
Posted by Jason Gunthorpe 2 weeks, 4 days ago
On Mon, Jan 19, 2026 at 09:19:02PM +0000, Lorenzo Stoakes wrote:
> We introduced the bitmap VMA type vma_flags_t in the aptly named commit
> 9ea35a25d51b ("mm: introduce VMA flags bitmap type") in order to permit
> future growth in VMA flags and to prevent the asinine requirement that VMA
> flags be available to 64-bit kernels only if they happened to use a bit
> number about 32-bits.
> 
> This is a long-term project as there are very many users of VMA flags
> within the kernel that need to be updated in order to utilise this new
> type.
> 
> In order to further this aim, this series adds a number of helper functions
> to enable ordinary interactions with VMA flags - that is testing, setting
> and clearing them.
> 
> In order to make working with VMA bit numbers less cumbersome this series
> introduces the mk_vma_flags() helper macro which generates a vma_flags_t
> from a variadic parameter list, e.g.:
> 
> 	vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
> 					 VMA_EXEC_BIT);

I didn't try to check every conversion, but the whole approach looks
nice to me and I think this design is ergonomic!

Jason
Re: [PATCH RESEND 00/12] mm: add bitmap VMA flag helpers and convert all mmap_prepare to use them
Posted by Lorenzo Stoakes 2 weeks, 4 days ago
On Mon, Jan 19, 2026 at 07:14:43PM -0400, Jason Gunthorpe wrote:
> On Mon, Jan 19, 2026 at 09:19:02PM +0000, Lorenzo Stoakes wrote:
> > We introduced the bitmap VMA type vma_flags_t in the aptly named commit
> > 9ea35a25d51b ("mm: introduce VMA flags bitmap type") in order to permit
> > future growth in VMA flags and to prevent the asinine requirement that VMA
> > flags be available to 64-bit kernels only if they happened to use a bit
> > number about 32-bits.
> >
> > This is a long-term project as there are very many users of VMA flags
> > within the kernel that need to be updated in order to utilise this new
> > type.
> >
> > In order to further this aim, this series adds a number of helper functions
> > to enable ordinary interactions with VMA flags - that is testing, setting
> > and clearing them.
> >
> > In order to make working with VMA bit numbers less cumbersome this series
> > introduces the mk_vma_flags() helper macro which generates a vma_flags_t
> > from a variadic parameter list, e.g.:
> >
> > 	vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
> > 					 VMA_EXEC_BIT);
>
> I didn't try to check every conversion, but the whole approach looks
> nice to me and I think this design is ergonomic!

Thanks :) I have spent a _lot_ of time experimenting with different approaches
and making sure the compiler generates reasonable assembly, obviously inspired
by your suggestion that something like this was viable (I lacked faith in the
compiler doing this well previously).

I did initially have the macro be even 'cleverer' so you could do e.g.:

vma_flags_set(&flags, READ, WRITE, EXEC);

And have the macro prefix VMA_ and suffix _BIT but... a. we #define READ, WRITE
and b. it means the symbols are no longer anything to do with real symbols that
exist in the source so would be confusing.

At any rate once the conversion is complete we can drop the _BIT and make it a
little nicer.

>
> Jason

Cheers, Lorenzo