* [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
@ 2025-12-05 17:50 Lorenzo Stoakes
2025-12-05 17:52 ` Lorenzo Stoakes
` (4 more replies)
0 siblings, 5 replies; 21+ messages in thread
From: Lorenzo Stoakes @ 2025-12-05 17:50 UTC (permalink / raw)
To: Andrew Morton
Cc: David Hildenbrand, Liam R . Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, oliver.sang,
linux-mm, linux-kernel
Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
how VMA flags are declared, utilising an enum of VMA bit values and
ifdef-fery VM_xxx flag declarations via macro.
As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
the newly introduced VMA bit numbers.
However, use of this macro results in apparently unfortunate macro
expansion and resulted in a performance degradation.This appears to be due
to the (__force int), which is required for the sparse typechecking to
work.
Avoid macro expansion issues by simply using 1UL << bitnum.
Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202512041634.150c7e4f-lkp@intel.com
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
Andrew - note I've referenced the linux-next commit number above, could you
replace with the upstream commit hash once your PR is taken? Thanks!
include/linux/mm.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index a2f38fb68840..c4438b30c140 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -395,7 +395,8 @@ enum {
#undef DECLARE_VMA_BIT
#undef DECLARE_VMA_BIT_ALIAS
-#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
+#define INIT_VM_FLAG(name) (1UL << (__force int)(VMA_ ## name ## _BIT))
+
#define VM_READ INIT_VM_FLAG(READ)
#define VM_WRITE INIT_VM_FLAG(WRITE)
#define VM_EXEC INIT_VM_FLAG(EXEC)
--
2.52.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 17:50 [PATCH] mm: avoid use of BIT() macro for initialising VMA flags Lorenzo Stoakes
@ 2025-12-05 17:52 ` Lorenzo Stoakes
2025-12-05 18:43 ` David Laight
` (3 subsequent siblings)
4 siblings, 0 replies; 21+ messages in thread
From: Lorenzo Stoakes @ 2025-12-05 17:52 UTC (permalink / raw)
To: Andrew Morton
Cc: David Hildenbrand, Liam R . Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, oliver.sang,
linux-mm, linux-kernel
On Fri, Dec 05, 2025 at 05:50:37PM +0000, Lorenzo Stoakes wrote:
> Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> how VMA flags are declared, utilising an enum of VMA bit values and
> ifdef-fery VM_xxx flag declarations via macro.
>
> As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> the newly introduced VMA bit numbers.
>
> However, use of this macro results in apparently unfortunate macro
> expansion and resulted in a performance degradation.This appears to be due
> to the (__force int), which is required for the sparse typechecking to
> work.
>
> Avoid macro expansion issues by simply using 1UL << bitnum.
>
> Reported-by: kernel test robot <oliver.sang@intel.com>
> Closes: https://lore.kernel.org/oe-lkp/202512041634.150c7e4f-lkp@intel.com
> Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Sorry forget to add Fixes tag... :)
Please update with that also when the PR is upstream apologies :P
> ---
>
> Andrew - note I've referenced the linux-next commit number above, could you
> replace with the upstream commit hash once your PR is taken? Thanks!
>
> include/linux/mm.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index a2f38fb68840..c4438b30c140 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -395,7 +395,8 @@ enum {
> #undef DECLARE_VMA_BIT
> #undef DECLARE_VMA_BIT_ALIAS
>
> -#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
> +#define INIT_VM_FLAG(name) (1UL << (__force int)(VMA_ ## name ## _BIT))
> +
> #define VM_READ INIT_VM_FLAG(READ)
> #define VM_WRITE INIT_VM_FLAG(WRITE)
> #define VM_EXEC INIT_VM_FLAG(EXEC)
> --
> 2.52.0
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 17:50 [PATCH] mm: avoid use of BIT() macro for initialising VMA flags Lorenzo Stoakes
2025-12-05 17:52 ` Lorenzo Stoakes
@ 2025-12-05 18:43 ` David Laight
2025-12-05 19:18 ` Lorenzo Stoakes
2025-12-05 19:56 ` John Hubbard
` (2 subsequent siblings)
4 siblings, 1 reply; 21+ messages in thread
From: David Laight @ 2025-12-05 18:43 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Fri, 5 Dec 2025 17:50:37 +0000
Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> how VMA flags are declared, utilising an enum of VMA bit values and
> ifdef-fery VM_xxx flag declarations via macro.
>
> As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> the newly introduced VMA bit numbers.
>
> However, use of this macro results in apparently unfortunate macro
> expansion and resulted in a performance degradation.This appears to be due
> to the (__force int), which is required for the sparse typechecking to
> work.
Does sparse complain if you just add 0? As in:
#define INIT_VM_FLAG(name) BIT(VMA_ ## name ## _BIT + 0u)
That should change the type without affecting what BIT() expands to.
David
>
> Avoid macro expansion issues by simply using 1UL << bitnum.
>
> Reported-by: kernel test robot <oliver.sang@intel.com>
> Closes: https://lore.kernel.org/oe-lkp/202512041634.150c7e4f-lkp@intel.com
> Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> ---
>
> Andrew - note I've referenced the linux-next commit number above, could you
> replace with the upstream commit hash once your PR is taken? Thanks!
>
> include/linux/mm.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index a2f38fb68840..c4438b30c140 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -395,7 +395,8 @@ enum {
> #undef DECLARE_VMA_BIT
> #undef DECLARE_VMA_BIT_ALIAS
>
> -#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
> +#define INIT_VM_FLAG(name) (1UL << (__force int)(VMA_ ## name ## _BIT))
> +
> #define VM_READ INIT_VM_FLAG(READ)
> #define VM_WRITE INIT_VM_FLAG(WRITE)
> #define VM_EXEC INIT_VM_FLAG(EXEC)
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 18:43 ` David Laight
@ 2025-12-05 19:18 ` Lorenzo Stoakes
2025-12-05 21:34 ` David Laight
2025-12-05 21:49 ` David Laight
0 siblings, 2 replies; 21+ messages in thread
From: Lorenzo Stoakes @ 2025-12-05 19:18 UTC (permalink / raw)
To: David Laight
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Fri, Dec 05, 2025 at 06:43:42PM +0000, David Laight wrote:
> On Fri, 5 Dec 2025 17:50:37 +0000
> Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
>
> > Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> > how VMA flags are declared, utilising an enum of VMA bit values and
> > ifdef-fery VM_xxx flag declarations via macro.
> >
> > As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> > the newly introduced VMA bit numbers.
> >
> > However, use of this macro results in apparently unfortunate macro
> > expansion and resulted in a performance degradation.This appears to be due
> > to the (__force int), which is required for the sparse typechecking to
> > work.
>
> Does sparse complain if you just add 0? As in:
> #define INIT_VM_FLAG(name) BIT(VMA_ ## name ## _BIT + 0u)
>
> That should change the type without affecting what BIT() expands to.
Thanks, checked that and unfortunately that doesn't satisfy sparse :)
I don't think it's too crazy to use 1UL << here, just very frustrating (TM)
that this is an issue.
<insert rant about C macros here>
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 17:50 [PATCH] mm: avoid use of BIT() macro for initialising VMA flags Lorenzo Stoakes
2025-12-05 17:52 ` Lorenzo Stoakes
2025-12-05 18:43 ` David Laight
@ 2025-12-05 19:56 ` John Hubbard
2025-12-06 16:42 ` Lorenzo Stoakes
2025-12-05 20:15 ` Andrew Morton
2025-12-06 1:14 ` Al Viro
4 siblings, 1 reply; 21+ messages in thread
From: John Hubbard @ 2025-12-05 19:56 UTC (permalink / raw)
To: Lorenzo Stoakes, Andrew Morton
Cc: David Hildenbrand, Liam R . Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, oliver.sang,
linux-mm, linux-kernel
On 12/5/25 9:50 AM, Lorenzo Stoakes wrote:
> Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> how VMA flags are declared, utilising an enum of VMA bit values and
> ifdef-fery VM_xxx flag declarations via macro.
>
> As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> the newly introduced VMA bit numbers.
>
> However, use of this macro results in apparently unfortunate macro
> expansion and resulted in a performance degradation.This appears to be due
> to the (__force int), which is required for the sparse typechecking to
> work.
>
> Avoid macro expansion issues by simply using 1UL << bitnum.
>
> Reported-by: kernel test robot <oliver.sang@intel.com>
> Closes: https://lore.kernel.org/oe-lkp/202512041634.150c7e4f-lkp@intel.com
> Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> ---
>
> Andrew - note I've referenced the linux-next commit number above, could you
> replace with the upstream commit hash once your PR is taken? Thanks!
>
> include/linux/mm.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index a2f38fb68840..c4438b30c140 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -395,7 +395,8 @@ enum {
> #undef DECLARE_VMA_BIT
> #undef DECLARE_VMA_BIT_ALIAS
>
> -#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
> +#define INIT_VM_FLAG(name) (1UL << (__force int)(VMA_ ## name ## _BIT))
OK, so now maybe we don't need all of the rust/bindings/bindings_helper.h
changes? Those were because Rust's bindgen doesn't properly handle
nested macros, as I recall.
> +
> #define VM_READ INIT_VM_FLAG(READ)
> #define VM_WRITE INIT_VM_FLAG(WRITE)
> #define VM_EXEC INIT_VM_FLAG(EXEC)
> --
> 2.52.0
>
thanks,
--
John Hubbard
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 17:50 [PATCH] mm: avoid use of BIT() macro for initialising VMA flags Lorenzo Stoakes
` (2 preceding siblings ...)
2025-12-05 19:56 ` John Hubbard
@ 2025-12-05 20:15 ` Andrew Morton
2025-12-05 20:18 ` David Hildenbrand (Red Hat)
2025-12-06 0:40 ` Stephen Rothwell
2025-12-06 1:14 ` Al Viro
4 siblings, 2 replies; 21+ messages in thread
From: Andrew Morton @ 2025-12-05 20:15 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: David Hildenbrand, Liam R . Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, oliver.sang,
linux-mm, linux-kernel
On Fri, 5 Dec 2025 17:50:37 +0000 Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
>
> ...
>
> Andrew - note I've referenced the linux-next commit number above, could you
> replace with the upstream commit hash once your PR is taken? Thanks!
That's in mm-stable so the hash shouldn't be changing.
I'm not really sure what's the best way to determine this. I use
hp2:/usr/src/mm> git tag --contains 2b6a3f061f11
mm-everything-2025-11-29-19-43
mm-everything-2025-12-01-19-02
mm-everything-2025-12-03-23-49
mm-everything-2025-12-05-00-55
mm-stable-2025-12-03-21-26
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 20:15 ` Andrew Morton
@ 2025-12-05 20:18 ` David Hildenbrand (Red Hat)
2025-12-06 0:40 ` Stephen Rothwell
1 sibling, 0 replies; 21+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-12-05 20:18 UTC (permalink / raw)
To: Andrew Morton, Lorenzo Stoakes
Cc: Liam R . Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, oliver.sang, linux-mm,
linux-kernel
On 12/5/25 21:15, Andrew Morton wrote:
> On Fri, 5 Dec 2025 17:50:37 +0000 Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
>
>> Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
>>
>> ...
>>
>> Andrew - note I've referenced the linux-next commit number above, could you
>> replace with the upstream commit hash once your PR is taken? Thanks!
>
> That's in mm-stable so the hash shouldn't be changing.
>
>
> I'm not really sure what's the best way to determine this. I use
>
> hp2:/usr/src/mm> git tag --contains 2b6a3f061f11
> mm-everything-2025-11-29-19-43
> mm-everything-2025-12-01-19-02
> mm-everything-2025-12-03-23-49
> mm-everything-2025-12-05-00-55
> mm-stable-2025-12-03-21-26
I asked myself the same question a couple of times.
Maybe this?
$ git branch -r --contains 2b6a3f061f11
mm/mm-everything
mm/mm-new
mm/mm-stable
--
Cheers
David
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 19:18 ` Lorenzo Stoakes
@ 2025-12-05 21:34 ` David Laight
2025-12-06 16:43 ` Lorenzo Stoakes
2025-12-05 21:49 ` David Laight
1 sibling, 1 reply; 21+ messages in thread
From: David Laight @ 2025-12-05 21:34 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Fri, 5 Dec 2025 19:18:56 +0000
Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> On Fri, Dec 05, 2025 at 06:43:42PM +0000, David Laight wrote:
> > On Fri, 5 Dec 2025 17:50:37 +0000
> > Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> >
> > > Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> > > how VMA flags are declared, utilising an enum of VMA bit values and
> > > ifdef-fery VM_xxx flag declarations via macro.
> > >
> > > As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> > > the newly introduced VMA bit numbers.
> > >
> > > However, use of this macro results in apparently unfortunate macro
> > > expansion and resulted in a performance degradation.This appears to be due
> > > to the (__force int), which is required for the sparse typechecking to
> > > work.
> >
> > Does sparse complain if you just add 0? As in:
> > #define INIT_VM_FLAG(name) BIT(VMA_ ## name ## _BIT + 0u)
> >
> > That should change the type without affecting what BIT() expands to.
>
> Thanks, checked that and unfortunately that doesn't satisfy sparse :)
>
> I don't think it's too crazy to use 1UL << here, just very frustrating (TM)
> that this is an issue.
I might use some of my copious spare time (ha) to see why BIT() fails.
I bet it is just too complex for its own good.
Personally I'm fine with both explicit (1ul << n) and hex constants.
The latter are definitely most useful if you ever look at hexdumps.
At the moment I'm trying to fix bitfield.h so you don't get compile errors
on lines that are 18KB long.
Found a new version in linux-next - has its own set of new bugs as well
as more of the old ones.
David
>
> <insert rant about C macros here>
>
> Cheers, Lorenzo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 19:18 ` Lorenzo Stoakes
2025-12-05 21:34 ` David Laight
@ 2025-12-05 21:49 ` David Laight
2025-12-06 16:47 ` Lorenzo Stoakes
1 sibling, 1 reply; 21+ messages in thread
From: David Laight @ 2025-12-05 21:49 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Fri, 5 Dec 2025 19:18:56 +0000
Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> On Fri, Dec 05, 2025 at 06:43:42PM +0000, David Laight wrote:
> > On Fri, 5 Dec 2025 17:50:37 +0000
> > Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> >
> > > Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> > > how VMA flags are declared, utilising an enum of VMA bit values and
> > > ifdef-fery VM_xxx flag declarations via macro.
> > >
> > > As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> > > the newly introduced VMA bit numbers.
> > >
> > > However, use of this macro results in apparently unfortunate macro
> > > expansion and resulted in a performance degradation.This appears to be due
> > > to the (__force int), which is required for the sparse typechecking to
> > > work.
> >
> > Does sparse complain if you just add 0? As in:
> > #define INIT_VM_FLAG(name) BIT(VMA_ ## name ## _BIT + 0u)
> >
> > That should change the type without affecting what BIT() expands to.
>
> Thanks, checked that and unfortunately that doesn't satisfy sparse :)
Oh - it is that __bitwise that causes grief.
> I don't think it's too crazy to use 1UL << here, just very frustrating (TM)
> that this is an issue.
Did you try getting DECLARE_VMA_BIT to define both the bit number and the
bit flag and put them both into the anonymous enum?
Or are there other reasons for not doing that?
>
> <insert rant about C macros here>
Add rant about the compiler thinking anon enums are doing anything other
than defining constants.
David
>
> Cheers, Lorenzo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 20:15 ` Andrew Morton
2025-12-05 20:18 ` David Hildenbrand (Red Hat)
@ 2025-12-06 0:40 ` Stephen Rothwell
2025-12-06 3:12 ` Andrew Morton
1 sibling, 1 reply; 21+ messages in thread
From: Stephen Rothwell @ 2025-12-06 0:40 UTC (permalink / raw)
To: Andrew Morton
Cc: Lorenzo Stoakes, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 723 bytes --]
Hi Andrew,
On Fri, 5 Dec 2025 12:15:01 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
>
> I'm not really sure what's the best way to determine this. I use
>
> hp2:/usr/src/mm> git tag --contains 2b6a3f061f11
> mm-everything-2025-11-29-19-43
> mm-everything-2025-12-01-19-02
> mm-everything-2025-12-03-23-49
> mm-everything-2025-12-05-00-55
> mm-stable-2025-12-03-21-26
>
What does "git branch --contains 2b6a3f061f11" say in your tree?
In my linux-next tree it says (I need the -r to check remote branches):
$ git branch -r --contains 2b6a3f061f11
mm-stable/mm-stable
mm-unstable/mm-unstable
but I don't export my remotes to my published tree.
--
Cheers,
Stephen Rothwell
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 17:50 [PATCH] mm: avoid use of BIT() macro for initialising VMA flags Lorenzo Stoakes
` (3 preceding siblings ...)
2025-12-05 20:15 ` Andrew Morton
@ 2025-12-06 1:14 ` Al Viro
2025-12-06 1:26 ` Al Viro
4 siblings, 1 reply; 21+ messages in thread
From: Al Viro @ 2025-12-06 1:14 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Fri, Dec 05, 2025 at 05:50:37PM +0000, Lorenzo Stoakes wrote:
> Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> how VMA flags are declared, utilising an enum of VMA bit values and
> ifdef-fery VM_xxx flag declarations via macro.
>
> As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> the newly introduced VMA bit numbers.
>
> However, use of this macro results in apparently unfortunate macro
> expansion and resulted in a performance degradation.This appears to be due
> to the (__force int), which is required for the sparse typechecking to
> work.
> -#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
> +#define INIT_VM_FLAG(name) (1UL << (__force int)(VMA_ ## name ## _BIT))
What the hell is __bitwise doing on these enum values?
Could we please get rid of that ridiculous cargo-culting?
Bitwise operations on BIT NUMBERS make no sense whatsoever; why are those
declared __bitwise?
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-06 1:14 ` Al Viro
@ 2025-12-06 1:26 ` Al Viro
2025-12-06 12:35 ` Vlastimil Babka
0 siblings, 1 reply; 21+ messages in thread
From: Al Viro @ 2025-12-06 1:26 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Sat, Dec 06, 2025 at 01:14:35AM +0000, Al Viro wrote:
> On Fri, Dec 05, 2025 at 05:50:37PM +0000, Lorenzo Stoakes wrote:
> > Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> > how VMA flags are declared, utilising an enum of VMA bit values and
> > ifdef-fery VM_xxx flag declarations via macro.
> >
> > As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> > the newly introduced VMA bit numbers.
> >
> > However, use of this macro results in apparently unfortunate macro
> > expansion and resulted in a performance degradation.This appears to be due
> > to the (__force int), which is required for the sparse typechecking to
> > work.
>
> > -#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
> > +#define INIT_VM_FLAG(name) (1UL << (__force int)(VMA_ ## name ## _BIT))
>
> What the hell is __bitwise doing on these enum values?
> Could we please get rid of that ridiculous cargo-culting?
>
> Bitwise operations on BIT NUMBERS make no sense whatsoever; why are those
> declared __bitwise?
FWIW, bitwise does make sense for things like (1 << SOME_CONSTANT);
then you get warned about arithmetics and conversions to integer
for those, with bitwise operations explicitly allowed.
VM_... are such; VMA_..._BIT are not. VM_READ | VM_EXEC is fine;
VM_READ + 14 is nonsense and should be warned about. That's where
__bitwise would make sense. On bit numbers it's not - what makes
VMA_BIT_MAYREAD ^ VMA_BIT_SHARED any better than 3 * VMA_BIT_MAYREAD?
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-06 0:40 ` Stephen Rothwell
@ 2025-12-06 3:12 ` Andrew Morton
2025-12-06 16:35 ` Lorenzo Stoakes
0 siblings, 1 reply; 21+ messages in thread
From: Andrew Morton @ 2025-12-06 3:12 UTC (permalink / raw)
To: Stephen Rothwell
Cc: Lorenzo Stoakes, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Sat, 6 Dec 2025 11:40:34 +1100 Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> Hi Andrew,
>
> On Fri, 5 Dec 2025 12:15:01 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
> >
> > I'm not really sure what's the best way to determine this. I use
> >
> > hp2:/usr/src/mm> git tag --contains 2b6a3f061f11
> > mm-everything-2025-11-29-19-43
> > mm-everything-2025-12-01-19-02
> > mm-everything-2025-12-03-23-49
> > mm-everything-2025-12-05-00-55
> > mm-stable-2025-12-03-21-26
> >
>
> What does "git branch --contains 2b6a3f061f11" say in your tree?
hp2:/usr/src/mm> git branch --contains 2b6a3f061f11
* linus
mm-everything
mm-new
mm-stable
mm-unstable
hp2:/usr/src/mm> git branch -r --contains 2b6a3f061f11
linus/master
origin/mm-everything
origin/mm-new
origin/mm-stable
origin/mm-unstable
kinda random, but it tells me "that's in mm-stable", which is what counts.
> In my linux-next tree it says (I need the -r to check remote branches):
>
> $ git branch -r --contains 2b6a3f061f11
> mm-stable/mm-stable
> mm-unstable/mm-unstable
>
> but I don't export my remotes to my published tree.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-06 1:26 ` Al Viro
@ 2025-12-06 12:35 ` Vlastimil Babka
2025-12-06 16:34 ` Lorenzo Stoakes
0 siblings, 1 reply; 21+ messages in thread
From: Vlastimil Babka @ 2025-12-06 12:35 UTC (permalink / raw)
To: Al Viro, Lorenzo Stoakes
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, oliver.sang,
linux-mm, linux-kernel
On 12/6/25 2:26 AM, Al Viro wrote:
> On Sat, Dec 06, 2025 at 01:14:35AM +0000, Al Viro wrote:
>> On Fri, Dec 05, 2025 at 05:50:37PM +0000, Lorenzo Stoakes wrote:
>>> Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
>>> how VMA flags are declared, utilising an enum of VMA bit values and
>>> ifdef-fery VM_xxx flag declarations via macro.
>>>
>>> As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
>>> the newly introduced VMA bit numbers.
>>>
>>> However, use of this macro results in apparently unfortunate macro
>>> expansion and resulted in a performance degradation.This appears to be due
>>> to the (__force int), which is required for the sparse typechecking to
>>> work.
>>
>>> -#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
>>> +#define INIT_VM_FLAG(name) (1UL << (__force int)(VMA_ ## name ## _BIT))
>>
>> What the hell is __bitwise doing on these enum values?
>> Could we please get rid of that ridiculous cargo-culting?
>>
>> Bitwise operations on BIT NUMBERS make no sense whatsoever; why are those
>> declared __bitwise?
I was confused by this too at first when reviewing, but instead of the angry
display above, simply asked the author and got answers.
Comment says:
/**
* typedef vma_flag_t - specifies an individual VMA flag by bit number.
*
* This value is made type safe by sparse to avoid passing invalid flag values
* around.
*/
typedef int __bitwise vma_flag_t;
It's done as documented in Documentation/dev-tools/sparse.rst section
"Using sparse for typechecking".
So yeah the keyword is __bitwise and indeed we don't perform bitwise operations
on the VM_ values, in fact we don't perform any operations without __force
casting them back first, to catch when they are used by mistake.
It's not cargo-culting, IIRC it catched a bug in an early version of the
patch itself.
I wouldn't mind if sparse provided a different keyword than __bitwise
for this use case to make it less misleading. Or even better if we could
make the compiler itself treat vma_flag_t as a "special int" that can't
be implicitly cast to a normal int, so we don't have to rely on sparse
checks to catch those.
> FWIW, bitwise does make sense for things like (1 << SOME_CONSTANT);
> then you get warned about arithmetics and conversions to integer
> for those, with bitwise operations explicitly allowed.
>
> VM_... are such; VMA_..._BIT are not. VM_READ | VM_EXEC is fine;
> VM_READ + 14 is nonsense and should be warned about. That's where
> __bitwise would make sense. On bit numbers it's not - what makes
> VMA_BIT_MAYREAD ^ VMA_BIT_SHARED any better than 3 * VMA_BIT_MAYREAD?
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-06 12:35 ` Vlastimil Babka
@ 2025-12-06 16:34 ` Lorenzo Stoakes
0 siblings, 0 replies; 21+ messages in thread
From: Lorenzo Stoakes @ 2025-12-06 16:34 UTC (permalink / raw)
To: Vlastimil Babka
Cc: Al Viro, Andrew Morton, David Hildenbrand, Liam R . Howlett,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, oliver.sang,
linux-mm, linux-kernel
On Sat, Dec 06, 2025 at 01:35:51PM +0100, Vlastimil Babka wrote:
> On 12/6/25 2:26 AM, Al Viro wrote:
> > On Sat, Dec 06, 2025 at 01:14:35AM +0000, Al Viro wrote:
> >> On Fri, Dec 05, 2025 at 05:50:37PM +0000, Lorenzo Stoakes wrote:
> >>> Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> >>> how VMA flags are declared, utilising an enum of VMA bit values and
> >>> ifdef-fery VM_xxx flag declarations via macro.
> >>>
> >>> As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> >>> the newly introduced VMA bit numbers.
> >>>
> >>> However, use of this macro results in apparently unfortunate macro
> >>> expansion and resulted in a performance degradation.This appears to be due
> >>> to the (__force int), which is required for the sparse typechecking to
> >>> work.
> >>
> >>> -#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
> >>> +#define INIT_VM_FLAG(name) (1UL << (__force int)(VMA_ ## name ## _BIT))
> >>
> >> What the hell is __bitwise doing on these enum values?
> >> Could we please get rid of that ridiculous cargo-culting?
> >>
> >> Bitwise operations on BIT NUMBERS make no sense whatsoever; why are those
> >> declared __bitwise?
>
> I was confused by this too at first when reviewing, but instead of the angry
> display above, simply asked the author and got answers.
>
> Comment says:
>
> /**
> * typedef vma_flag_t - specifies an individual VMA flag by bit number.
> *
> * This value is made type safe by sparse to avoid passing invalid flag values
> * around.
> */
> typedef int __bitwise vma_flag_t;
>
> It's done as documented in Documentation/dev-tools/sparse.rst section
> "Using sparse for typechecking".
>
> So yeah the keyword is __bitwise and indeed we don't perform bitwise operations
> on the VM_ values, in fact we don't perform any operations without __force
> casting them back first, to catch when they are used by mistake.
> It's not cargo-culting, IIRC it catched a bug in an early version of the
> patch itself.
>
> I wouldn't mind if sparse provided a different keyword than __bitwise
> for this use case to make it less misleading. Or even better if we could
> make the compiler itself treat vma_flag_t as a "special int" that can't
> be implicitly cast to a normal int, so we don't have to rely on sparse
> checks to catch those.
>
Yup precisely - this was entirely to avoid issues with passing a VM_xxx flag
around when a VMA bit number is required which is a kind of bug that would be
_really easy_ to do otherwise.
vma_flags_set(..., VM_READ);
Reads perfectly but sets the write bit instead of the read bit, for instance.
Yes this is a hack, but does the job, and the sparse documentation doesn't
dissuade.
I agree with Vlasta that really we should provide an __explicit_type or
whatever annotation for this usage.
>
> > FWIW, bitwise does make sense for things like (1 << SOME_CONSTANT);
> > then you get warned about arithmetics and conversions to integer
> > for those, with bitwise operations explicitly allowed.
> >
> > VM_... are such; VMA_..._BIT are not. VM_READ | VM_EXEC is fine;
> > VM_READ + 14 is nonsense and should be warned about. That's where
> > __bitwise would make sense. On bit numbers it's not - what makes
> > VMA_BIT_MAYREAD ^ VMA_BIT_SHARED any better than 3 * VMA_BIT_MAYREAD?
>
The issue isn't so much the operations, and yes obviously VMA_MAYREAD_BIT ^
VMA_MAYREAD_SHARED makes no sense, but nobody in their right mind would be
doing that anyway right?
I'm not using sparse attributes here to enforce basic baseline sanity, but
rather to avoid the aforementioned class of bug, and it works very
effectively.
I did speak to Vlasta about a struct foo { int val; }; type thing, but
sadly then we can't have them in an enum, and we put them in an enum
because otherwise tooling like drgn, rust, etc. find it harder to get
access to the type, and it is in fact a useful way of defining these
values, as they naturally do belong to an enum (unique, individual values).
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-06 3:12 ` Andrew Morton
@ 2025-12-06 16:35 ` Lorenzo Stoakes
0 siblings, 0 replies; 21+ messages in thread
From: Lorenzo Stoakes @ 2025-12-06 16:35 UTC (permalink / raw)
To: Andrew Morton
Cc: Stephen Rothwell, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Fri, Dec 05, 2025 at 07:12:55PM -0800, Andrew Morton wrote:
> On Sat, 6 Dec 2025 11:40:34 +1100 Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>
> > Hi Andrew,
> >
> > On Fri, 5 Dec 2025 12:15:01 -0800 Andrew Morton <akpm@linux-foundation.org> wrote:
> > >
> > > I'm not really sure what's the best way to determine this. I use
> > >
> > > hp2:/usr/src/mm> git tag --contains 2b6a3f061f11
> > > mm-everything-2025-11-29-19-43
> > > mm-everything-2025-12-01-19-02
> > > mm-everything-2025-12-03-23-49
> > > mm-everything-2025-12-05-00-55
> > > mm-stable-2025-12-03-21-26
> > >
> >
> > What does "git branch --contains 2b6a3f061f11" say in your tree?
>
> hp2:/usr/src/mm> git branch --contains 2b6a3f061f11
> * linus
> mm-everything
> mm-new
> mm-stable
> mm-unstable
> hp2:/usr/src/mm> git branch -r --contains 2b6a3f061f11
> linus/master
> origin/mm-everything
> origin/mm-new
> origin/mm-stable
> origin/mm-unstable
>
> kinda random, but it tells me "that's in mm-stable", which is what counts.
>
> > In my linux-next tree it says (I need the -r to check remote branches):
> >
> > $ git branch -r --contains 2b6a3f061f11
> > mm-stable/mm-stable
> > mm-unstable/mm-unstable
> >
> > but I don't export my remotes to my published tree.
Thanks guys for confirming, this is therefore less work all round :)
Though Andrew do please add the Fixes tag that I foolishly forgot to
include, thanks!
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 19:56 ` John Hubbard
@ 2025-12-06 16:42 ` Lorenzo Stoakes
0 siblings, 0 replies; 21+ messages in thread
From: Lorenzo Stoakes @ 2025-12-06 16:42 UTC (permalink / raw)
To: John Hubbard
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Fri, Dec 05, 2025 at 11:56:32AM -0800, John Hubbard wrote:
> On 12/5/25 9:50 AM, Lorenzo Stoakes wrote:
> > Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> > how VMA flags are declared, utilising an enum of VMA bit values and
> > ifdef-fery VM_xxx flag declarations via macro.
> >
> > As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> > the newly introduced VMA bit numbers.
> >
> > However, use of this macro results in apparently unfortunate macro
> > expansion and resulted in a performance degradation.This appears to be due
> > to the (__force int), which is required for the sparse typechecking to
> > work.
> >
> > Avoid macro expansion issues by simply using 1UL << bitnum.
> >
> > Reported-by: kernel test robot <oliver.sang@intel.com>
> > Closes: https://lore.kernel.org/oe-lkp/202512041634.150c7e4f-lkp@intel.com
> > Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> > ---
> >
> > Andrew - note I've referenced the linux-next commit number above, could you
> > replace with the upstream commit hash once your PR is taken? Thanks!
> >
> > include/linux/mm.h | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index a2f38fb68840..c4438b30c140 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -395,7 +395,8 @@ enum {
> > #undef DECLARE_VMA_BIT
> > #undef DECLARE_VMA_BIT_ALIAS
> >
> > -#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT)
> > +#define INIT_VM_FLAG(name) (1UL << (__force int)(VMA_ ## name ## _BIT))
>
> OK, so now maybe we don't need all of the rust/bindings/bindings_helper.h
> changes? Those were because Rust's bindgen doesn't properly handle
> nested macros, as I recall.
Ah seems you're right, I just tried a clang/rust build with those dropped and it
worked fine.
Have added to TODO to send a patch to remove those after this one lands, thanks!
Cheers, Lorenzo
>
> > +
> > #define VM_READ INIT_VM_FLAG(READ)
> > #define VM_WRITE INIT_VM_FLAG(WRITE)
> > #define VM_EXEC INIT_VM_FLAG(EXEC)
> > --
> > 2.52.0
> >
>
> thanks,
> --
> John Hubbard
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 21:34 ` David Laight
@ 2025-12-06 16:43 ` Lorenzo Stoakes
2025-12-08 16:42 ` Lorenzo Stoakes
0 siblings, 1 reply; 21+ messages in thread
From: Lorenzo Stoakes @ 2025-12-06 16:43 UTC (permalink / raw)
To: David Laight
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Fri, Dec 05, 2025 at 09:34:49PM +0000, David Laight wrote:
> On Fri, 5 Dec 2025 19:18:56 +0000
> Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
>
> > On Fri, Dec 05, 2025 at 06:43:42PM +0000, David Laight wrote:
> > > On Fri, 5 Dec 2025 17:50:37 +0000
> > > Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> > >
> > > > Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> > > > how VMA flags are declared, utilising an enum of VMA bit values and
> > > > ifdef-fery VM_xxx flag declarations via macro.
> > > >
> > > > As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> > > > the newly introduced VMA bit numbers.
> > > >
> > > > However, use of this macro results in apparently unfortunate macro
> > > > expansion and resulted in a performance degradation.This appears to be due
> > > > to the (__force int), which is required for the sparse typechecking to
> > > > work.
> > >
> > > Does sparse complain if you just add 0? As in:
> > > #define INIT_VM_FLAG(name) BIT(VMA_ ## name ## _BIT + 0u)
> > >
> > > That should change the type without affecting what BIT() expands to.
> >
> > Thanks, checked that and unfortunately that doesn't satisfy sparse :)
> >
> > I don't think it's too crazy to use 1UL << here, just very frustrating (TM)
> > that this is an issue.
>
> I might use some of my copious spare time (ha) to see why BIT() fails.
> I bet it is just too complex for its own good.
> Personally I'm fine with both explicit (1ul << n) and hex constants.
> The latter are definitely most useful if you ever look at hexdumps.
Thanks :) yeah I just didn't want to go down that rabbit hole myself as I seemed
to have the answer and wanted to get it fixed, but obviously am quite curious as
to what on earth is causing that.
>
> At the moment I'm trying to fix bitfield.h so you don't get compile errors
> on lines that are 18KB long.
:)
>
> Found a new version in linux-next - has its own set of new bugs as well
> as more of the old ones.
>
> David
>
> >
> > <insert rant about C macros here>
> >
> > Cheers, Lorenzo
>
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-05 21:49 ` David Laight
@ 2025-12-06 16:47 ` Lorenzo Stoakes
0 siblings, 0 replies; 21+ messages in thread
From: Lorenzo Stoakes @ 2025-12-06 16:47 UTC (permalink / raw)
To: David Laight
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Fri, Dec 05, 2025 at 09:49:40PM +0000, David Laight wrote:
> On Fri, 5 Dec 2025 19:18:56 +0000
> Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
>
> > On Fri, Dec 05, 2025 at 06:43:42PM +0000, David Laight wrote:
> > > On Fri, 5 Dec 2025 17:50:37 +0000
> > > Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> > >
> > > > Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> > > > how VMA flags are declared, utilising an enum of VMA bit values and
> > > > ifdef-fery VM_xxx flag declarations via macro.
> > > >
> > > > As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> > > > the newly introduced VMA bit numbers.
> > > >
> > > > However, use of this macro results in apparently unfortunate macro
> > > > expansion and resulted in a performance degradation.This appears to be due
> > > > to the (__force int), which is required for the sparse typechecking to
> > > > work.
> > >
> > > Does sparse complain if you just add 0? As in:
> > > #define INIT_VM_FLAG(name) BIT(VMA_ ## name ## _BIT + 0u)
> > >
> > > That should change the type without affecting what BIT() expands to.
> >
> > Thanks, checked that and unfortunately that doesn't satisfy sparse :)
>
> Oh - it is that __bitwise that causes grief.
Well, if a sparse build is not enabled this tag is just removed (as is __force).
>
> > I don't think it's too crazy to use 1UL << here, just very frustrating (TM)
> > that this is an issue.
>
> Did you try getting DECLARE_VMA_BIT to define both the bit number and the
> bit flag and put them both into the anonymous enum?
> Or are there other reasons for not doing that?
I did and we can't do that because it results in errors like 'enum constant in
boolean context [-Werror=int-in-bool-context]' as clearly VM_xxx flags are used
in many different contexts in the kernel many of which seem incompatible with
enum constants (even though... they should be equivalent, at least in theory?)
>
> >
> > <insert rant about C macros here>
>
> Add rant about the compiler thinking anon enums are doing anything other
> than defining constants.
Right yes :)
I put these in an enum in part to make life easier for tools like drgn to be
able to find these values (the guys asked about this explicitly). But also it
makes sense for them to be in an enum!
Really the VM_xxx flags are at least in theory a temporary hack until everything
can use bit numbers... assuming I can find a way to do that without causing
performance regressions :)
The perf regression here was - rather unexpected - however - I must say!
>
> David
>
> >
> > Cheers, Lorenzo
>
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-06 16:43 ` Lorenzo Stoakes
@ 2025-12-08 16:42 ` Lorenzo Stoakes
2025-12-08 18:57 ` David Laight
0 siblings, 1 reply; 21+ messages in thread
From: Lorenzo Stoakes @ 2025-12-08 16:42 UTC (permalink / raw)
To: David Laight
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Sat, Dec 06, 2025 at 04:43:57PM +0000, Lorenzo Stoakes wrote:
> On Fri, Dec 05, 2025 at 09:34:49PM +0000, David Laight wrote:
> > On Fri, 5 Dec 2025 19:18:56 +0000
> > Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> >
> > > On Fri, Dec 05, 2025 at 06:43:42PM +0000, David Laight wrote:
> > > > On Fri, 5 Dec 2025 17:50:37 +0000
> > > > Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> > > >
> > > > > Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> > > > > how VMA flags are declared, utilising an enum of VMA bit values and
> > > > > ifdef-fery VM_xxx flag declarations via macro.
> > > > >
> > > > > As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> > > > > the newly introduced VMA bit numbers.
> > > > >
> > > > > However, use of this macro results in apparently unfortunate macro
> > > > > expansion and resulted in a performance degradation.This appears to be due
> > > > > to the (__force int), which is required for the sparse typechecking to
> > > > > work.
> > > >
> > > > Does sparse complain if you just add 0? As in:
> > > > #define INIT_VM_FLAG(name) BIT(VMA_ ## name ## _BIT + 0u)
> > > >
> > > > That should change the type without affecting what BIT() expands to.
> > >
> > > Thanks, checked that and unfortunately that doesn't satisfy sparse :)
> > >
> > > I don't think it's too crazy to use 1UL << here, just very frustrating (TM)
> > > that this is an issue.
> >
> > I might use some of my copious spare time (ha) to see why BIT() fails.
> > I bet it is just too complex for its own good.
> > Personally I'm fine with both explicit (1ul << n) and hex constants.
> > The latter are definitely most useful if you ever look at hexdumps.
>
> Thanks :) yeah I just didn't want to go down that rabbit hole myself as I seemed
> to have the answer and wanted to get it fixed, but obviously am quite curious as
> to what on earth is causing that.
I did wonder about _calc_vm_trans(), given the 'interesting' stuff it does.
Maybe I should fiddle with that and see...
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH] mm: avoid use of BIT() macro for initialising VMA flags
2025-12-08 16:42 ` Lorenzo Stoakes
@ 2025-12-08 18:57 ` David Laight
0 siblings, 0 replies; 21+ messages in thread
From: David Laight @ 2025-12-08 18:57 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Andrew Morton, David Hildenbrand, Liam R . Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
oliver.sang, linux-mm, linux-kernel
On Mon, 8 Dec 2025 16:42:43 +0000
Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> On Sat, Dec 06, 2025 at 04:43:57PM +0000, Lorenzo Stoakes wrote:
> > On Fri, Dec 05, 2025 at 09:34:49PM +0000, David Laight wrote:
> > > On Fri, 5 Dec 2025 19:18:56 +0000
> > > Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> > >
> > > > On Fri, Dec 05, 2025 at 06:43:42PM +0000, David Laight wrote:
> > > > > On Fri, 5 Dec 2025 17:50:37 +0000
> > > > > Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> > > > >
> > > > > > Commit 2b6a3f061f11 ("mm: declare VMA flags by bit") significantly changed
> > > > > > how VMA flags are declared, utilising an enum of VMA bit values and
> > > > > > ifdef-fery VM_xxx flag declarations via macro.
> > > > > >
> > > > > > As part of this change, it uses INIT_VM_FLAG() to define VM_xxx flags from
> > > > > > the newly introduced VMA bit numbers.
> > > > > >
> > > > > > However, use of this macro results in apparently unfortunate macro
> > > > > > expansion and resulted in a performance degradation.This appears to be due
> > > > > > to the (__force int), which is required for the sparse typechecking to
> > > > > > work.
> > > > >
> > > > > Does sparse complain if you just add 0? As in:
> > > > > #define INIT_VM_FLAG(name) BIT(VMA_ ## name ## _BIT + 0u)
> > > > >
> > > > > That should change the type without affecting what BIT() expands to.
> > > >
> > > > Thanks, checked that and unfortunately that doesn't satisfy sparse :)
> > > >
> > > > I don't think it's too crazy to use 1UL << here, just very frustrating (TM)
> > > > that this is an issue.
> > >
> > > I might use some of my copious spare time (ha) to see why BIT() fails.
> > > I bet it is just too complex for its own good.
> > > Personally I'm fine with both explicit (1ul << n) and hex constants.
> > > The latter are definitely most useful if you ever look at hexdumps.
> >
> > Thanks :) yeah I just didn't want to go down that rabbit hole myself as I seemed
> > to have the answer and wanted to get it fixed, but obviously am quite curious as
> > to what on earth is causing that.
>
> I did wonder about _calc_vm_trans(), given the 'interesting' stuff it does.
>
> Maybe I should fiddle with that and see...
Hmmm...
/*
* Optimisation macro. It is equivalent to:
* (x & bit1) ? bit2 : 0
* but this version is faster.
* ("bit1" and "bit2" must be single bits)
*/
#define _calc_vm_trans(x, bit1, bit2) \
((!(bit1) || !(bit2)) ? 0 : \
((bit1) <= (bit2) ? ((x) & (bit1)) * ((bit2) / (bit1)) \
: ((x) & (bit1)) / ((bit1) / (bit2))))
The comment fails to mention it is only sane for constants.
If nothing else 9 expansions of BIT() are going to generate a very
long line.
For starters make it a statement expression and use __auto_type _bit1 = bit1.
Then add a check for both _bit1 and _bit2 being constants.
It is also worth checking the compiler doesn't do it for you.
Looks like gcc 7.1 onwards generate the 'optimised' code.
https://godbolt.org/z/EGGE56E3r
David
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2025-12-08 18:57 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-05 17:50 [PATCH] mm: avoid use of BIT() macro for initialising VMA flags Lorenzo Stoakes
2025-12-05 17:52 ` Lorenzo Stoakes
2025-12-05 18:43 ` David Laight
2025-12-05 19:18 ` Lorenzo Stoakes
2025-12-05 21:34 ` David Laight
2025-12-06 16:43 ` Lorenzo Stoakes
2025-12-08 16:42 ` Lorenzo Stoakes
2025-12-08 18:57 ` David Laight
2025-12-05 21:49 ` David Laight
2025-12-06 16:47 ` Lorenzo Stoakes
2025-12-05 19:56 ` John Hubbard
2025-12-06 16:42 ` Lorenzo Stoakes
2025-12-05 20:15 ` Andrew Morton
2025-12-05 20:18 ` David Hildenbrand (Red Hat)
2025-12-06 0:40 ` Stephen Rothwell
2025-12-06 3:12 ` Andrew Morton
2025-12-06 16:35 ` Lorenzo Stoakes
2025-12-06 1:14 ` Al Viro
2025-12-06 1:26 ` Al Viro
2025-12-06 12:35 ` Vlastimil Babka
2025-12-06 16:34 ` Lorenzo Stoakes
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox