Re: [PATCH 4/4] mm: introduce and use VMA flag test helpers

From: Lorenzo Stoakes

Date: Thu Oct 30 2025 - 10:05:37 EST


On Thu, Oct 30, 2025 at 09:52:34AM -0300, Jason Gunthorpe wrote:
> On Thu, Oct 30, 2025 at 10:04:31AM +0000, Lorenzo Stoakes wrote:
> > It may also just be sensible to drop the vma_test() since I've named VMA flags
> > vma->flags which is kinda neat and not so painful to do:
> >
> > if (vma_flags_test(&vma->flags, VMA_READ_BIT)) {
> > }
> >
> > Another note - I do hope to drop the _BIT at some point. But it felt egregious
> > to do so _now_ since VM_READ, VMA_READ are so close it'd be _super_ easy to
> > mistake the two.
>
> Yes, you should have the bit until the non-bit versions are removed
> entirely.
>
> > Buuut I'm guessing actually you're thinking more of getting rid of
> > vm_flags_word_[and, any, all]() all of which take VM_xxx parameters.
>
> Yes
>
> > > few instructions.
> > >
> >
> > Well I'm not sure, hopefully. Maybe I need to test this and see exactly what the
> > it comes up with.
> >
> > I mean you could in theory have:
> >
> > vma_flags_any(&vma->flags, OR_VMA_FLAGS(VMA_PFNMAP_BIT, VMA_SEALED_BIT))
>
> 'any' here means any of the given bits set, yes? So the operation is
>
> (flags & to_test) != 0

Yeah sorry, you're right. nd __bitmap_and() for BITS_PER_LONG aligned bitmap
size (which it always will be) amoutns to:

for (k = 0; k < lim; k++)
result |= (dst[k] = bitmap1[k] & bitmap2[k]);

So yeah... ok interesting.

>
> Which is bitmap_and, not or. In this case the compiler goes word by
> word:

Yeah indeed.

>
> flags[0] & to_test[0] != 0
> flags[1] & to_test[1] != 0
>
> And constant propagation turns it into
> flags[1] & 0 != 0 ----> 0
>
> So the extra word just disappears.

Hmm on the assumption that we can construct a vma_flags_t that the compiler
knows to be constant... I wonder if:

int to_test[2];

to_test[0] |= 1 << SOME_CONST;
to_test[1] |= 1 << ANOTHER_CONST;

flags[0] & to_test[0]
flags[1] & to_test[1]

Will propagate like this.

But enough theory... I godbolt'd it and https://godbolt.org/z/8PW6PzK1f

Well knock me down with a feather modern compilers _are_ clever enough :)

I have underestimated this...

>
> Similarly if you want to do a set bit using or
>
> flags[0] = flags[0] | to_set[0]
> flags[1] = flags[1] | to_set[1]
>
> And again constant propagation
> flags[1] = flags[1] | 0 ------> NOP
>
> > I feel like we're going to need the 'special first word' stuff permanently for
> > performance reasons.
>
> I think not, look above..

No, this is quite interesting then, I was concerned about this!

>
> > > Then everything only works with _BIT and we don't have the special
> > > first word situation.
> >
> > In any case we still need to maintain the word stuff for legacy purposes at
> > least to handle the existing vm_flags_*() interfaces until the work is complete.
>
> I think it will be hard to sustain this idea that some operations do
> not work on the bits in the second word, it is just not very natural
> going forward..

Yeah of course it's far from ideal.

>
> So I'd try to structure things to remove the non-BIT users before
> adding multi-word..

Yeah, OK well your point has been made here, the compiler _is_ smart enough
to save us here :)

Let's avoid this first word stuff altogether then.

>
> Jason

Cheers, Lorenzo