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