* [PATCH next 01/14] overflow: Reduce expansion of __type_max()
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-01-21 20:59 ` Kees Cook
2026-02-02 16:45 ` Yury Norov
2026-01-21 14:57 ` [PATCH next 02/14] kbuild: Add W=c for additional compile time checks david.laight.linux
` (12 subsequent siblings)
13 siblings, 2 replies; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
Change '(x - 1) + x' to '2 * (x - 1) + 1' to avoid expanding the
non-trivial __type_half_max() twice.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
include/linux/overflow.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index 736f633b2d5f..4f014d55ab25 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -31,7 +31,7 @@
* credit to Christian Biere.
*/
#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
-#define __type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
+#define __type_max(T) ((T)(2 * (__type_half_max(T) - 1) + 1))
#define type_max(t) __type_max(typeof(t))
#define __type_min(T) ((T)((T)-type_max(T)-(T)1))
#define type_min(t) __type_min(typeof(t))
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH next 01/14] overflow: Reduce expansion of __type_max()
2026-01-21 14:57 ` [PATCH next 01/14] overflow: Reduce expansion of __type_max() david.laight.linux
@ 2026-01-21 20:59 ` Kees Cook
2026-02-02 16:45 ` Yury Norov
1 sibling, 0 replies; 56+ messages in thread
From: Kees Cook @ 2026-01-21 20:59 UTC (permalink / raw)
To: david.laight.linux
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Andrew Morton
On Wed, Jan 21, 2026 at 02:57:18PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> Change '(x - 1) + x' to '2 * (x - 1) + 1' to avoid expanding the
> non-trivial __type_half_max() twice.
>
> Signed-off-by: David Laight <david.laight.linux@gmail.com>
Sure!
Reviewed-by: Kees Cook <kees@kernel.org>
--
Kees Cook
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 01/14] overflow: Reduce expansion of __type_max()
2026-01-21 14:57 ` [PATCH next 01/14] overflow: Reduce expansion of __type_max() david.laight.linux
2026-01-21 20:59 ` Kees Cook
@ 2026-02-02 16:45 ` Yury Norov
1 sibling, 0 replies; 56+ messages in thread
From: Yury Norov @ 2026-02-02 16:45 UTC (permalink / raw)
To: david.laight.linux
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Wed, Jan 21, 2026 at 02:57:18PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> Change '(x - 1) + x' to '2 * (x - 1) + 1' to avoid expanding the
> non-trivial __type_half_max() twice.
>
> Signed-off-by: David Laight <david.laight.linux@gmail.com>
Thanks!
Reviewed-by: Yury Norov <ynorov@nvidia.com>
> ---
> include/linux/overflow.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> index 736f633b2d5f..4f014d55ab25 100644
> --- a/include/linux/overflow.h
> +++ b/include/linux/overflow.h
> @@ -31,7 +31,7 @@
> * credit to Christian Biere.
> */
> #define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
> -#define __type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
> +#define __type_max(T) ((T)(2 * (__type_half_max(T) - 1) + 1))
> #define type_max(t) __type_max(typeof(t))
> #define __type_min(T) ((T)((T)-type_max(T)-(T)1))
> #define type_min(t) __type_min(typeof(t))
> --
> 2.39.5
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH next 02/14] kbuild: Add W=c for additional compile time checks
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
2026-01-21 14:57 ` [PATCH next 01/14] overflow: Reduce expansion of __type_max() david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-02-02 18:33 ` Yury Norov
2026-01-21 14:57 ` [PATCH next 03/14] media: videobuf2-core: Use static_assert() for sanity check david.laight.linux
` (11 subsequent siblings)
13 siblings, 1 reply; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
Some compile time checks significantly bloat the pre-processor output
(particularly when the get nested).
Since the checks aren't really needed on every compilation enable with
W=c (adds -DKBUILD_EXTRA_WARNc) so the checks can be enabled per-build.
Make W=1 imply W=c so the build-bot includes the checks.
As well as reducing the bloat from existing checks (like those in
GENMASK() and FIELD_PREP()) it lets additional checks be added
while there are still 'false positives' without breaking normal builds.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
scripts/Makefile.warn | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/scripts/Makefile.warn b/scripts/Makefile.warn
index 68e6fafcb80c..e8a799850973 100644
--- a/scripts/Makefile.warn
+++ b/scripts/Makefile.warn
@@ -2,8 +2,9 @@
# ==========================================================================
# make W=... settings
#
-# There are four warning groups enabled by W=1, W=2, W=3, and W=e
-# They are independent, and can be combined like W=12 or W=123e.
+# There are five warning groups enabled by W=c, W=1, W=2, W=3, and W=e
+# They are independent, and can be combined like W=12 or W=123e,
+# except that W=1 implies W=c.
# ==========================================================================
# Default set of warnings, always enabled
@@ -109,6 +110,13 @@ KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion)
KBUILD_CFLAGS += -Wunused
+#
+# W=c - Expensive compile-time checks, implied by W=1
+#
+ifneq ($(findstring c, $(KBUILD_EXTRA_WARN))$(findstring 1, $(KBUILD_EXTRA_WARN)),)
+KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARNc
+endif
+
#
# W=1 - warnings which may be relevant and do not occur too often
#
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH next 02/14] kbuild: Add W=c for additional compile time checks
2026-01-21 14:57 ` [PATCH next 02/14] kbuild: Add W=c for additional compile time checks david.laight.linux
@ 2026-02-02 18:33 ` Yury Norov
2026-02-02 20:07 ` David Laight
0 siblings, 1 reply; 56+ messages in thread
From: Yury Norov @ 2026-02-02 18:33 UTC (permalink / raw)
To: david.laight.linux
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Wed, Jan 21, 2026 at 02:57:19PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> Some compile time checks significantly bloat the pre-processor output
> (particularly when the get nested).
> Since the checks aren't really needed on every compilation enable with
> W=c (adds -DKBUILD_EXTRA_WARNc) so the checks can be enabled per-build.
> Make W=1 imply W=c so the build-bot includes the checks.
>
> As well as reducing the bloat from existing checks (like those in
> GENMASK() and FIELD_PREP()) it lets additional checks be added
> while there are still 'false positives' without breaking normal builds.
>
> Signed-off-by: David Laight <david.laight.linux@gmail.com>
Honestly I don't understand this. AFAIU, you've outlined a list of
compiler warnings that slow the compilation down, and you group them
under 'W=c' option.
What is the use case for it outside of your series. I think, a typical
user would find more value in an option that enables some warnings but
doesn't sacrifices performance. Can you consider flipping the 'W=c'
behavior?
Can you please explicitly mention warnings included in W=c vs W=1? Can
you report compilation time for W=0, W=1 and W=c? What if one needs to
enable fast/slow warnings from 2nd or 3rd level? Would W=2c or W=3c
work in this case?
What does this 'c' stands for?
Thanks,
Yury
> ---
> scripts/Makefile.warn | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/scripts/Makefile.warn b/scripts/Makefile.warn
> index 68e6fafcb80c..e8a799850973 100644
> --- a/scripts/Makefile.warn
> +++ b/scripts/Makefile.warn
> @@ -2,8 +2,9 @@
> # ==========================================================================
> # make W=... settings
> #
> -# There are four warning groups enabled by W=1, W=2, W=3, and W=e
> -# They are independent, and can be combined like W=12 or W=123e.
> +# There are five warning groups enabled by W=c, W=1, W=2, W=3, and W=e
> +# They are independent, and can be combined like W=12 or W=123e,
> +# except that W=1 implies W=c.
> # ==========================================================================
>
> # Default set of warnings, always enabled
> @@ -109,6 +110,13 @@ KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion)
>
> KBUILD_CFLAGS += -Wunused
>
> +#
> +# W=c - Expensive compile-time checks, implied by W=1
> +#
> +ifneq ($(findstring c, $(KBUILD_EXTRA_WARN))$(findstring 1, $(KBUILD_EXTRA_WARN)),)
> +KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARNc
> +endif
> +
> #
> # W=1 - warnings which may be relevant and do not occur too often
> #
> --
> 2.39.5
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 02/14] kbuild: Add W=c for additional compile time checks
2026-02-02 18:33 ` Yury Norov
@ 2026-02-02 20:07 ` David Laight
2026-02-03 4:47 ` Nathan Chancellor
2026-02-03 19:41 ` Yury Norov
0 siblings, 2 replies; 56+ messages in thread
From: David Laight @ 2026-02-02 20:07 UTC (permalink / raw)
To: Yury Norov
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Mon, 2 Feb 2026 13:33:22 -0500
Yury Norov <ynorov@nvidia.com> wrote:
> On Wed, Jan 21, 2026 at 02:57:19PM +0000, david.laight.linux@gmail.com wrote:
> > From: David Laight <david.laight.linux@gmail.com>
> >
> > Some compile time checks significantly bloat the pre-processor output
> > (particularly when the get nested).
> > Since the checks aren't really needed on every compilation enable with
> > W=c (adds -DKBUILD_EXTRA_WARNc) so the checks can be enabled per-build.
> > Make W=1 imply W=c so the build-bot includes the checks.
> >
> > As well as reducing the bloat from existing checks (like those in
> > GENMASK() and FIELD_PREP()) it lets additional checks be added
> > while there are still 'false positives' without breaking normal builds.
> >
> > Signed-off-by: David Laight <david.laight.linux@gmail.com>
>
> Honestly I don't understand this. AFAIU, you've outlined a list of
> compiler warnings that slow the compilation down, and you group them
> under 'W=c' option.
>
> What is the use case for it outside of your series. I think, a typical
> user would find more value in an option that enables some warnings but
> doesn't sacrifices performance.
All the compile-time warnings slow down the compilation.
Even apparently trivial ones (like the check in the generic READ_ONCE()
that the size is 1, 2, 4 or 8 bytes) have a measurable effect.
The code a typical user compiles won't have anything that trips any of
the compile-time asserts.
They only really happen when compiling new code or adding new checks.
> Can you consider flipping the 'W=c' behavior?
Why, most of the time you don't want the checks because the code is
known to pass them all.
It also means it can be used for new checks before all the bugs (and
false positives) have been fixed.
I did think of just enabling the checks for W=1 builds, but that makes
it far to hard to enable them.
As it is you can use W=ce to enable them and stop on warnings and errors.
Also W=xxx can only really add checks (there are some checks for it being
non-empty). Documenting that W=x stopped the 'x' checks being done
would be painful.
> Can you please explicitly mention warnings included in W=c vs W=1? Can
> you report compilation time for W=0, W=1 and W=c? What if one needs to
> enable fast/slow warnings from 2nd or 3rd level? Would W=2c or W=3c
> work in this case?
The W=123 options are all completely independent, my W=c is the same.
I'm not sure it is sane to run W=2 rather than W=12, but it is allowed.
I made W=1 imply W=1c so that the build bot would pick up the extra checks.
Apart from that all the 'W' flags are independent.
W=123 fiddle with the command line -W options and set -DKBUILD_EXTRA_WARN[123]
so that files can include extra checks.
W=c just sets the equivalent -D option.
> What does this 'c' stands for?
Anything you want it to :-)
Discussion session arranged for 2pm-5pm by the bike shed.
In some sense it is 'more warnings than default, but not as many as W=1'.
Like a lot of the W=1 warnings I wanted to be able to pick up 'code quality'
issues without breaking the build for normal people.
There are definitely some other checks that could be relegated to W=c
once it has been added.
I'd also like to add some checks to min_t/max_t/clamp_t to pick up the
worst of the dodgy/broken code without having to get all the patches
accepted before the test itself is committed.
Tests for code like clamp_t(u32, u64_val, 0, ~0u) (yes there are some)
tend to get very long and may be problematic if enabled by default
(I got burnt by the 10MB expansion of nested min().)
David
>
> Thanks,
> Yury
>
> > ---
> > scripts/Makefile.warn | 12 ++++++++++--
> > 1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/scripts/Makefile.warn b/scripts/Makefile.warn
> > index 68e6fafcb80c..e8a799850973 100644
> > --- a/scripts/Makefile.warn
> > +++ b/scripts/Makefile.warn
> > @@ -2,8 +2,9 @@
> > # ==========================================================================
> > # make W=... settings
> > #
> > -# There are four warning groups enabled by W=1, W=2, W=3, and W=e
> > -# They are independent, and can be combined like W=12 or W=123e.
> > +# There are five warning groups enabled by W=c, W=1, W=2, W=3, and W=e
> > +# They are independent, and can be combined like W=12 or W=123e,
> > +# except that W=1 implies W=c.
> > # ==========================================================================
> >
> > # Default set of warnings, always enabled
> > @@ -109,6 +110,13 @@ KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion)
> >
> > KBUILD_CFLAGS += -Wunused
> >
> > +#
> > +# W=c - Expensive compile-time checks, implied by W=1
> > +#
> > +ifneq ($(findstring c, $(KBUILD_EXTRA_WARN))$(findstring 1, $(KBUILD_EXTRA_WARN)),)
> > +KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARNc
> > +endif
> > +
> > #
> > # W=1 - warnings which may be relevant and do not occur too often
> > #
> > --
> > 2.39.5
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 02/14] kbuild: Add W=c for additional compile time checks
2026-02-02 20:07 ` David Laight
@ 2026-02-03 4:47 ` Nathan Chancellor
2026-02-03 11:14 ` David Laight
2026-02-03 19:41 ` Yury Norov
1 sibling, 1 reply; 56+ messages in thread
From: Nathan Chancellor @ 2026-02-03 4:47 UTC (permalink / raw)
To: David Laight
Cc: Yury Norov, Greg Kroah-Hartman, Thomas Gleixner, Peter Zijlstra,
Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann, linux-arch,
linux-kernel, Yury Norov, Lucas De Marchi, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton
On Mon, Feb 02, 2026 at 08:07:43PM +0000, David Laight wrote:
> On Mon, 2 Feb 2026 13:33:22 -0500
> Yury Norov <ynorov@nvidia.com> wrote:
>
> > On Wed, Jan 21, 2026 at 02:57:19PM +0000, david.laight.linux@gmail.com wrote:
> > > From: David Laight <david.laight.linux@gmail.com>
> > >
> > > Some compile time checks significantly bloat the pre-processor output
> > > (particularly when the get nested).
> > > Since the checks aren't really needed on every compilation enable with
> > > W=c (adds -DKBUILD_EXTRA_WARNc) so the checks can be enabled per-build.
> > > Make W=1 imply W=c so the build-bot includes the checks.
> > >
> > > As well as reducing the bloat from existing checks (like those in
> > > GENMASK() and FIELD_PREP()) it lets additional checks be added
> > > while there are still 'false positives' without breaking normal builds.
> > >
> > > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> >
> > Honestly I don't understand this. AFAIU, you've outlined a list of
> > compiler warnings that slow the compilation down, and you group them
> > under 'W=c' option.
> >
> > What is the use case for it outside of your series. I think, a typical
> > user would find more value in an option that enables some warnings but
> > doesn't sacrifices performance.
>
> All the compile-time warnings slow down the compilation.
> Even apparently trivial ones (like the check in the generic READ_ONCE()
> that the size is 1, 2, 4 or 8 bytes) have a measurable effect.
What kind of difference are we talking about here across a regular
build?
> The code a typical user compiles won't have anything that trips any of
> the compile-time asserts.
> They only really happen when compiling new code or adding new checks.
>
> > Can you consider flipping the 'W=c' behavior?
>
> Why, most of the time you don't want the checks because the code is
> known to pass them all.
>
> It also means it can be used for new checks before all the bugs (and
> false positives) have been fixed.
> I did think of just enabling the checks for W=1 builds, but that makes
> it far to hard to enable them.
> As it is you can use W=ce to enable them and stop on warnings and errors.
>
> Also W=xxx can only really add checks (there are some checks for it being
> non-empty). Documenting that W=x stopped the 'x' checks being done
> would be painful.
Yeah, I don't think we should be overloading the meaning of W=.
> > Can you please explicitly mention warnings included in W=c vs W=1? Can
> > you report compilation time for W=0, W=1 and W=c? What if one needs to
> > enable fast/slow warnings from 2nd or 3rd level? Would W=2c or W=3c
> > work in this case?
>
> The W=123 options are all completely independent, my W=c is the same.
> I'm not sure it is sane to run W=2 rather than W=12, but it is allowed.
>
> I made W=1 imply W=1c so that the build bot would pick up the extra checks.
> Apart from that all the 'W' flags are independent.
> W=123 fiddle with the command line -W options and set -DKBUILD_EXTRA_WARN[123]
> so that files can include extra checks.
> W=c just sets the equivalent -D option.
Why even have a different option then? You mention above placing the
checks in W=1 makes them too hard to enable but then you say that you
made W=1 imply W=c?
> > What does this 'c' stands for?
>
> Anything you want it to :-)
> Discussion session arranged for 2pm-5pm by the bike shed.
W=c already exists, it is documented as enabling extra Kconfig checks in
'make help'. Maybe W=x for "ex"pensive checks? Or maybe if we really
want W=c, maybe rename W=c to W=k for Kconfig? I do not really have a
strong preference.
> In some sense it is 'more warnings than default, but not as many as W=1'.
> Like a lot of the W=1 warnings I wanted to be able to pick up 'code quality'
> issues without breaking the build for normal people.
So something like a W=0.5? :)
> There are definitely some other checks that could be relegated to W=c
> once it has been added.
>
> I'd also like to add some checks to min_t/max_t/clamp_t to pick up the
> worst of the dodgy/broken code without having to get all the patches
> accepted before the test itself is committed.
> Tests for code like clamp_t(u32, u64_val, 0, ~0u) (yes there are some)
> tend to get very long and may be problematic if enabled by default
> (I got burnt by the 10MB expansion of nested min().)
I do not have a super strong opinion about this overall but it feels
like this is a bit of a slippery slope with warning fragmentation. I
think I would rather see these be treated like regular compiler warnings
where the majority of instances are cleaned up then it is added to W=1
to keep the tree clean.
Cheers,
Nathan
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 02/14] kbuild: Add W=c for additional compile time checks
2026-02-03 4:47 ` Nathan Chancellor
@ 2026-02-03 11:14 ` David Laight
0 siblings, 0 replies; 56+ messages in thread
From: David Laight @ 2026-02-03 11:14 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Yury Norov, Greg Kroah-Hartman, Thomas Gleixner, Peter Zijlstra,
Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann, linux-arch,
linux-kernel, Yury Norov, Lucas De Marchi, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton
On Mon, 2 Feb 2026 21:47:26 -0700
Nathan Chancellor <nathan@kernel.org> wrote:
> On Mon, Feb 02, 2026 at 08:07:43PM +0000, David Laight wrote:
> > On Mon, 2 Feb 2026 13:33:22 -0500
> > Yury Norov <ynorov@nvidia.com> wrote:
> >
> > > On Wed, Jan 21, 2026 at 02:57:19PM +0000, david.laight.linux@gmail.com wrote:
> > > > From: David Laight <david.laight.linux@gmail.com>
> > > >
> > > > Some compile time checks significantly bloat the pre-processor output
> > > > (particularly when the get nested).
> > > > Since the checks aren't really needed on every compilation enable with
> > > > W=c (adds -DKBUILD_EXTRA_WARNc) so the checks can be enabled per-build.
> > > > Make W=1 imply W=c so the build-bot includes the checks.
> > > >
> > > > As well as reducing the bloat from existing checks (like those in
> > > > GENMASK() and FIELD_PREP()) it lets additional checks be added
> > > > while there are still 'false positives' without breaking normal builds.
> > > >
> > > > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> > >
> > > Honestly I don't understand this. AFAIU, you've outlined a list of
> > > compiler warnings that slow the compilation down, and you group them
> > > under 'W=c' option.
> > >
> > > What is the use case for it outside of your series. I think, a typical
> > > user would find more value in an option that enables some warnings but
> > > doesn't sacrifices performance.
> >
> > All the compile-time warnings slow down the compilation.
> > Even apparently trivial ones (like the check in the generic READ_ONCE()
> > that the size is 1, 2, 4 or 8 bytes) have a measurable effect.
>
> What kind of difference are we talking about here across a regular
> build?
IIRC a couple of %.
I repeated a few builds with/without and it was much greater than the
variation between the builds.
That is a pretty trivial test, but there are a lot of READ_ONCE().
Find a few of those and the difference is significant.
>
> > The code a typical user compiles won't have anything that trips any of
> > the compile-time asserts.
> > They only really happen when compiling new code or adding new checks.
> >
> > > Can you consider flipping the 'W=c' behavior?
> >
> > Why, most of the time you don't want the checks because the code is
> > known to pass them all.
> >
> > It also means it can be used for new checks before all the bugs (and
> > false positives) have been fixed.
> > I did think of just enabling the checks for W=1 builds, but that makes
> > it far to hard to enable them.
> > As it is you can use W=ce to enable them and stop on warnings and errors.
> >
> > Also W=xxx can only really add checks (there are some checks for it being
> > non-empty). Documenting that W=x stopped the 'x' checks being done
> > would be painful.
>
> Yeah, I don't think we should be overloading the meaning of W=.
I did thing of supporting W=-e so that you can do W=1-e on a config
that enables WERROR, since there isn't much chance of a W=1e build
succeeding any time soon.
> > > Can you please explicitly mention warnings included in W=c vs W=1? Can
> > > you report compilation time for W=0, W=1 and W=c? What if one needs to
> > > enable fast/slow warnings from 2nd or 3rd level? Would W=2c or W=3c
> > > work in this case?
> >
> > The W=123 options are all completely independent, my W=c is the same.
> > I'm not sure it is sane to run W=2 rather than W=12, but it is allowed.
> >
> > I made W=1 imply W=1c so that the build bot would pick up the extra checks.
> > Apart from that all the 'W' flags are independent.
> > W=123 fiddle with the command line -W options and set -DKBUILD_EXTRA_WARN[123]
> > so that files can include extra checks.
> > W=c just sets the equivalent -D option.
>
> Why even have a different option then? You mention above placing the
> checks in W=1 makes them too hard to enable but then you say that you
> made W=1 imply W=c?
What I meant was it is hard to see the errors in a W=1 build.
So I wanted the enable the checks without picking up W=1.
>
> > > What does this 'c' stands for?
> >
> > Anything you want it to :-)
> > Discussion session arranged for 2pm-5pm by the bike shed.
>
> W=c already exists, it is documented as enabling extra Kconfig checks in
> 'make help'. Maybe W=x for "ex"pensive checks? Or maybe if we really
> want W=c, maybe rename W=c to W=k for Kconfig? I do not really have a
> strong preference.
It was 'c' for Compile time (a bit silly - but they are source 'compile-time'
tests rather then 'run-time' ones).
I'd only looked in makefile.warn for other uses.
> > In some sense it is 'more warnings than default, but not as many as W=1'.
> > Like a lot of the W=1 warnings I wanted to be able to pick up 'code quality'
> > issues without breaking the build for normal people.
>
> So something like a W=0.5? :)
That is really what I was looking for.
Perhaps setting -DKBUILD_WARN_LEVEL=level*10 would do?
So W=1 would set 10, W=2 20 (etc) with some scheme for setting intermediate
values (or at least (say) 5).
> > There are definitely some other checks that could be relegated to W=c
> > once it has been added.
> >
> > I'd also like to add some checks to min_t/max_t/clamp_t to pick up the
> > worst of the dodgy/broken code without having to get all the patches
> > accepted before the test itself is committed.
> > Tests for code like clamp_t(u32, u64_val, 0, ~0u) (yes there are some)
> > tend to get very long and may be problematic if enabled by default
> > (I got burnt by the 10MB expansion of nested min().)
>
> I do not have a super strong opinion about this overall but it feels
> like this is a bit of a slippery slope with warning fragmentation. I
> think I would rather see these be treated like regular compiler warnings
> where the majority of instances are cleaned up then it is added to W=1
> to keep the tree clean.
That is slightly different because (mostly) they are warnings from a
new compiler version so are picked up by people running the new compiler
before they break things and then added to W=1.
Adding an extra check to an existing header needs the change committing
to get test coverage somewhat earlier - maybe to force some reluctant
maintainers to actually fix their code.
I definitely needed to conditionally include the checks with W=e but
without W=1, this seemed the best way to do it.
David
>
> Cheers,
> Nathan
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 02/14] kbuild: Add W=c for additional compile time checks
2026-02-02 20:07 ` David Laight
2026-02-03 4:47 ` Nathan Chancellor
@ 2026-02-03 19:41 ` Yury Norov
1 sibling, 0 replies; 56+ messages in thread
From: Yury Norov @ 2026-02-03 19:41 UTC (permalink / raw)
To: David Laight
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Mon, Feb 02, 2026 at 08:07:43PM +0000, David Laight wrote:
> On Mon, 2 Feb 2026 13:33:22 -0500
> Yury Norov <ynorov@nvidia.com> wrote:
>
> > On Wed, Jan 21, 2026 at 02:57:19PM +0000, david.laight.linux@gmail.com wrote:
> > > From: David Laight <david.laight.linux@gmail.com>
> > >
> > > Some compile time checks significantly bloat the pre-processor output
> > > (particularly when the get nested).
> > > Since the checks aren't really needed on every compilation enable with
> > > W=c (adds -DKBUILD_EXTRA_WARNc) so the checks can be enabled per-build.
> > > Make W=1 imply W=c so the build-bot includes the checks.
> > >
> > > As well as reducing the bloat from existing checks (like those in
> > > GENMASK() and FIELD_PREP()) it lets additional checks be added
> > > while there are still 'false positives' without breaking normal builds.
> > >
> > > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> >
> > Honestly I don't understand this. AFAIU, you've outlined a list of
> > compiler warnings that slow the compilation down, and you group them
> > under 'W=c' option.
> >
> > What is the use case for it outside of your series. I think, a typical
> > user would find more value in an option that enables some warnings but
> > doesn't sacrifices performance.
>
> All the compile-time warnings slow down the compilation.
> Even apparently trivial ones (like the check in the generic READ_ONCE()
> that the size is 1, 2, 4 or 8 bytes) have a measurable effect.
>
> The code a typical user compiles won't have anything that trips any of
> the compile-time asserts.
> They only really happen when compiling new code or adding new checks.
>
> > Can you consider flipping the 'W=c' behavior?
>
> Why, most of the time you don't want the checks because the code is
> known to pass them all.
Please don't speculate for what others want. I already said very clearly
what I (probably) want - a performance-aware set of warnings. I can tell
you for sure what I do not want - a heavyweight subset of W=1 with a
partial coverage and similar compile time.
> It also means it can be used for new checks before all the bugs (and
> false positives) have been fixed.
> I did think of just enabling the checks for W=1 builds, but that makes
> it far to hard to enable them.
> As it is you can use W=ce to enable them and stop on warnings and errors.
>
> Also W=xxx can only really add checks (there are some checks for it being
> non-empty). Documenting that W=x stopped the 'x' checks being done
> would be painful.
>
> > Can you please explicitly mention warnings included in W=c vs W=1? Can
> > you report compilation time for W=0, W=1 and W=c? What if one needs to
> > enable fast/slow warnings from 2nd or 3rd level? Would W=2c or W=3c
> > work in this case?
>
> The W=123 options are all completely independent, my W=c is the same.
> I'm not sure it is sane to run W=2 rather than W=12, but it is allowed.
It is allowed and sane.
> I made W=1 imply W=1c so that the build bot would pick up the extra checks.
> Apart from that all the 'W' flags are independent.
> W=123 fiddle with the command line -W options and set -DKBUILD_EXTRA_WARN[123]
> so that files can include extra checks.
> W=c just sets the equivalent -D option.
Again, please:
- list all warnings included in W=c and their performance impact;
- report build time for W=1 vs W=c vs plain make;
- how would your new option work with W=2c, W=3c and so on.
> > What does this 'c' stands for?
>
> Anything you want it to :-)
> Discussion session arranged for 2pm-5pm by the bike shed.
Meaningless parameter names are not welcome. NAK.
> In some sense it is 'more warnings than default, but not as many as W=1'.
> Like a lot of the W=1 warnings I wanted to be able to pick up 'code quality'
> issues without breaking the build for normal people.
>
> There are definitely some other checks that could be relegated to W=c
> once it has been added.
>
> I'd also like to add some checks to min_t/max_t/clamp_t to pick up the
> worst of the dodgy/broken code without having to get all the patches
> accepted before the test itself is committed.
> Tests for code like clamp_t(u32, u64_val, 0, ~0u) (yes there are some)
> tend to get very long and may be problematic if enabled by default
> (I got burnt by the 10MB expansion of nested min().)
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH next 03/14] media: videobuf2-core: Use static_assert() for sanity check
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
2026-01-21 14:57 ` [PATCH next 01/14] overflow: Reduce expansion of __type_max() david.laight.linux
2026-01-21 14:57 ` [PATCH next 02/14] kbuild: Add W=c for additional compile time checks david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-01-21 14:57 ` [PATCH next 04/14] media: atomisp: " david.laight.linux
` (10 subsequent siblings)
13 siblings, 0 replies; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton, Tomasz Figa, Marek Szyprowski
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
Compile-time tests being added to BIT() make it an 'integer constant
expression' rather than a pre-processor expression for W=1 builds.
Change the BIT(PLANE_INDEX_BITS) != VIDEO_MAX_PLANES test to use
static_assert() so the code compiles.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
drivers/media/common/videobuf2/videobuf2-core.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
index 2df566f409b6..90dedab2aeb2 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -37,9 +37,9 @@
#define MAX_BUFFER_INDEX BIT_MASK(30 - PLANE_INDEX_SHIFT)
#define BUFFER_INDEX_MASK (MAX_BUFFER_INDEX - 1)
-#if BIT(PLANE_INDEX_BITS) != VIDEO_MAX_PLANES
-#error PLANE_INDEX_BITS order must be equal to VIDEO_MAX_PLANES
-#endif
+
+static_assert(BIT(PLANE_INDEX_BITS) == VIDEO_MAX_PLANES,
+ "PLANE_INDEX_BITS order must be equal to VIDEO_MAX_PLANES");
static int debug;
module_param(debug, int, 0644);
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH next 04/14] media: atomisp: Use static_assert() for sanity check
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (2 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 03/14] media: videobuf2-core: Use static_assert() for sanity check david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-01-21 14:57 ` [PATCH next 05/14] ixgbevf: Use C test for PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD david.laight.linux
` (9 subsequent siblings)
13 siblings, 0 replies; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
Compile-time tests being added to BIT() make it an 'integer constant
expression' rather than a pre-processor expression for W=1 builds.
Change the FRAC_ACC != BDS_UNIT test to use static_assert() so the code
compiles.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
.../kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h
index f7e5669d5125..31bce7b2650e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h
@@ -13,9 +13,8 @@
#define BDS_UNIT 8
#define FRAC_LOG 3
#define FRAC_ACC BIT(FRAC_LOG)
-#if FRAC_ACC != BDS_UNIT
-#error "FRAC_ACC and BDS_UNIT need to be merged into one define"
-#endif
+static_assert(FRAC_ACC == BDS_UNIT,
+ "FRAC_ACC and BDS_UNIT need to be merged into one define");
struct sh_css_isp_bds_params {
int baf_strength;
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH next 05/14] ixgbevf: Use C test for PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (3 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 04/14] media: atomisp: " david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-01-23 15:44 ` Simon Horman
2026-01-21 14:57 ` [PATCH next 06/14] asm-generic: include linux/bits.h not vdso/bits.h david.laight.linux
` (8 subsequent siblings)
13 siblings, 1 reply; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton, Tony Nguyen, Przemek Kitszel, David S. Miller,
Eric Dumazet, Jakub Kicinski, netdev
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
Compile-time tests being added to BIT() make it an 'integer constant
expression' rather than a pre-processor expression for W=1 builds.
This means BIT() can't be used in pre-processor conditional that
checks 'PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD'.
Change to use a normal 'if' statement, the compiler will optimise
away the unwanted code.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
.../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index d5ce20f47def..65dd5834d0cf 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -4166,9 +4166,6 @@ static int ixgbevf_xmit_frame_ring(struct sk_buff *skb,
u32 tx_flags = 0;
u16 count = TXD_USE_COUNT(skb_headlen(skb));
struct ixgbevf_ipsec_tx_data ipsec_tx = { 0 };
-#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
- unsigned short f;
-#endif
u8 hdr_len = 0;
u8 *dst_mac = skb_header_pointer(skb, 0, 0, NULL);
@@ -4183,15 +4180,15 @@ static int ixgbevf_xmit_frame_ring(struct sk_buff *skb,
* + 1 desc for context descriptor,
* otherwise try next time
*/
-#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
- for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[f];
+ if (PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD) {
+ for (unsigned int f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[f];
- count += TXD_USE_COUNT(skb_frag_size(frag));
+ count += TXD_USE_COUNT(skb_frag_size(frag));
+ }
+ } else {
+ count += skb_shinfo(skb)->nr_frags;
}
-#else
- count += skb_shinfo(skb)->nr_frags;
-#endif
if (ixgbevf_maybe_stop_tx(tx_ring, count + 3)) {
tx_ring->tx_stats.tx_busy++;
return NETDEV_TX_BUSY;
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH next 05/14] ixgbevf: Use C test for PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
2026-01-21 14:57 ` [PATCH next 05/14] ixgbevf: Use C test for PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD david.laight.linux
@ 2026-01-23 15:44 ` Simon Horman
0 siblings, 0 replies; 56+ messages in thread
From: Simon Horman @ 2026-01-23 15:44 UTC (permalink / raw)
To: david.laight.linux
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton, Tony Nguyen, Przemek Kitszel, David S. Miller,
Eric Dumazet, Jakub Kicinski, netdev
On Wed, Jan 21, 2026 at 02:57:22PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> Compile-time tests being added to BIT() make it an 'integer constant
> expression' rather than a pre-processor expression for W=1 builds.
>
> This means BIT() can't be used in pre-processor conditional that
> checks 'PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD'.
> Change to use a normal 'if' statement, the compiler will optimise
> away the unwanted code.
>
> Signed-off-by: David Laight <david.laight.linux@gmail.com>
Thanks David,
Other than the motivation above, I appreciate that this removes two
#ifdefs, improving readability (subjective) and compile coverage
(objective) of this code.
As an aside: I'm Not sure what your merge plan is for this patchset, and
only it and the cover letter hit my inbox, so I'm missing context. But
from a Networking PoV it seems that it could be sent as a stand-alone patch
to the iwl tree.
Regardless, feel free to add:
Reviewed-by: Simon Horman <horms@kernel.org>
...
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH next 06/14] asm-generic: include linux/bits.h not vdso/bits.h
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (4 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 05/14] ixgbevf: Use C test for PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-01-21 14:57 ` [PATCH next 07/14] x86/tlb: " david.laight.linux
` (7 subsequent siblings)
13 siblings, 0 replies; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
thread_info_tif.h isn't part of the vdso, use the linux/bits.h header.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
include/asm-generic/thread_info_tif.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/asm-generic/thread_info_tif.h b/include/asm-generic/thread_info_tif.h
index da1610a78f92..afdc23204674 100644
--- a/include/asm-generic/thread_info_tif.h
+++ b/include/asm-generic/thread_info_tif.h
@@ -2,7 +2,7 @@
#ifndef _ASM_GENERIC_THREAD_INFO_TIF_H_
#define _ASM_GENERIC_THREAD_INFO_TIF_H_
-#include <vdso/bits.h>
+#include <linux/bits.h>
/* Bits 16-31 are reserved for architecture specific purposes */
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH next 07/14] x86/tlb: include linux/bits.h not vdso/bits.h
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (5 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 06/14] asm-generic: include linux/bits.h not vdso/bits.h david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-01-21 14:57 ` [PATCH next 08/14] bits: simplify GENMASK_TYPE() david.laight.linux
` (6 subsequent siblings)
13 siblings, 0 replies; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
asm/tlb.h isn't part of the vdso, use the linux/bits.h header.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
arch/x86/include/asm/tlb.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h
index 866ea78ba156..e61c6de73e70 100644
--- a/arch/x86/include/asm/tlb.h
+++ b/arch/x86/include/asm/tlb.h
@@ -7,7 +7,7 @@ static inline void tlb_flush(struct mmu_gather *tlb);
#include <asm-generic/tlb.h>
#include <linux/kernel.h>
-#include <vdso/bits.h>
+#include <linux/bits.h>
#include <vdso/page.h>
static inline void tlb_flush(struct mmu_gather *tlb)
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH next 08/14] bits: simplify GENMASK_TYPE()
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (6 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 07/14] x86/tlb: " david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-02-08 2:36 ` Yury Norov
2026-01-21 14:57 ` [PATCH next 09/14] bits: Change BIT_U8/16() and GENMASK_U8/16() to have unsigned values david.laight.linux
` (5 subsequent siblings)
13 siblings, 1 reply; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
Since the type is always unsigned (T)-1 is always the correct value
so there is no need to use type_max().
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
include/linux/bits.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/include/linux/bits.h b/include/linux/bits.h
index a40cc861b3a7..697318f2a47d 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -45,8 +45,7 @@
*/
#define GENMASK_TYPE(t, h, l) \
((t)(GENMASK_INPUT_CHECK(h, l) + \
- (type_max(t) << (l) & \
- type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
+ ((t)-1 << (l) & (t)-1 >> (BITS_PER_TYPE(t) - 1 - (h)))))
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
#define GENMASK_ULL(h, l) GENMASK_TYPE(unsigned long long, h, l)
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH next 08/14] bits: simplify GENMASK_TYPE()
2026-01-21 14:57 ` [PATCH next 08/14] bits: simplify GENMASK_TYPE() david.laight.linux
@ 2026-02-08 2:36 ` Yury Norov
2026-02-09 9:42 ` David Laight
0 siblings, 1 reply; 56+ messages in thread
From: Yury Norov @ 2026-02-08 2:36 UTC (permalink / raw)
To: david.laight.linux
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Wed, Jan 21, 2026 at 02:57:25PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> Since the type is always unsigned (T)-1 is always the correct value
> so there is no need to use type_max().
>
> Signed-off-by: David Laight <david.laight.linux@gmail.com>
Here you implicitly add a new restriction that all types passed in
GENMASK_TYPE() must be unsigned. Can you enforce it with
is_signed_type(), or at lease with a corresponding comment?
> ---
> include/linux/bits.h | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/include/linux/bits.h b/include/linux/bits.h
> index a40cc861b3a7..697318f2a47d 100644
> --- a/include/linux/bits.h
> +++ b/include/linux/bits.h
> @@ -45,8 +45,7 @@
> */
> #define GENMASK_TYPE(t, h, l) \
> ((t)(GENMASK_INPUT_CHECK(h, l) + \
> - (type_max(t) << (l) & \
> - type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
> + ((t)-1 << (l) & (t)-1 >> (BITS_PER_TYPE(t) - 1 - (h)))))
>
> #define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
> #define GENMASK_ULL(h, l) GENMASK_TYPE(unsigned long long, h, l)
> --
> 2.39.5
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 08/14] bits: simplify GENMASK_TYPE()
2026-02-08 2:36 ` Yury Norov
@ 2026-02-09 9:42 ` David Laight
0 siblings, 0 replies; 56+ messages in thread
From: David Laight @ 2026-02-09 9:42 UTC (permalink / raw)
To: Yury Norov
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Sat, 7 Feb 2026 21:36:57 -0500
Yury Norov <ynorov@nvidia.com> wrote:
> On Wed, Jan 21, 2026 at 02:57:25PM +0000, david.laight.linux@gmail.com wrote:
> > From: David Laight <david.laight.linux@gmail.com>
> >
> > Since the type is always unsigned (T)-1 is always the correct value
> > so there is no need to use type_max().
> >
> > Signed-off-by: David Laight <david.laight.linux@gmail.com>
>
> Here you implicitly add a new restriction that all types passed in
> GENMASK_TYPE() must be unsigned. Can you enforce it with
> is_signed_type(), or at lease with a corresponding comment?
GENMASK_TYPE() is an internal define used in the expansions of,
for example, GENMASK_U32() - it is always passed an unsigned type.
I don't really think it should be used elsewhere at all.
In any case I don't think it makes any difference.
The value or type_max(t) has to match BITS_PER_TYPE(t) or else
the result is wrong, so it has never worked for signed types.
I did try adding a signedness check to FIELD_GET(), there is one
place in the x86-64 build that uses a signed type and requires the
right shift sign extend.
That code (in the fault handler) probably ought to be changed.
David
>
> > ---
> > include/linux/bits.h | 3 +--
> > 1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/include/linux/bits.h b/include/linux/bits.h
> > index a40cc861b3a7..697318f2a47d 100644
> > --- a/include/linux/bits.h
> > +++ b/include/linux/bits.h
> > @@ -45,8 +45,7 @@
> > */
> > #define GENMASK_TYPE(t, h, l) \
> > ((t)(GENMASK_INPUT_CHECK(h, l) + \
> > - (type_max(t) << (l) & \
> > - type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
> > + ((t)-1 << (l) & (t)-1 >> (BITS_PER_TYPE(t) - 1 - (h)))))
> >
> > #define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
> > #define GENMASK_ULL(h, l) GENMASK_TYPE(unsigned long long, h, l)
> > --
> > 2.39.5
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH next 09/14] bits: Change BIT_U8/16() and GENMASK_U8/16() to have unsigned values
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (7 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 08/14] bits: simplify GENMASK_TYPE() david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-01-21 14:57 ` [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx() david.laight.linux
` (4 subsequent siblings)
13 siblings, 0 replies; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
Casting the value of BIT_U*() and GENMASK_U8() to (u8) is pointless.
Although it changes what typeof(BIT_U8()) returns the value will
always be promoted to 'signed int' before it is used.
Instead force the expression to be an unsigned type.
Avoids unexpected sign extension from, for example:
u64 v = BIT_U8(7) << 24;
Fix the KUNIT tests to match.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
include/linux/bits.h | 6 +++---
lib/tests/test_bits.c | 12 ++++++------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/include/linux/bits.h b/include/linux/bits.h
index 697318f2a47d..23bc94815569 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -44,8 +44,8 @@
* - GENMASK_U32(33, 15): doesn't fit in a u32
*/
#define GENMASK_TYPE(t, h, l) \
- ((t)(GENMASK_INPUT_CHECK(h, l) + \
- ((t)-1 << (l) & (t)-1 >> (BITS_PER_TYPE(t) - 1 - (h)))))
+ ((unsigned int)GENMASK_INPUT_CHECK(h, l) + \
+ ((t)-1 << (l) & (t)-1 >> (BITS_PER_TYPE(t) - 1 - (h))))
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
#define GENMASK_ULL(h, l) GENMASK_TYPE(unsigned long long, h, l)
@@ -67,7 +67,7 @@
#define BIT_INPUT_CHECK(type, nr) \
BUILD_BUG_ON_ZERO(const_true((nr) >= BITS_PER_TYPE(type)))
-#define BIT_TYPE(type, nr) ((type)(BIT_INPUT_CHECK(type, nr) + BIT_ULL(nr)))
+#define BIT_TYPE(type, nr) ((unsigned int)BIT_INPUT_CHECK(type, nr) + ((type)1 << (nr)))
#define BIT_U8(nr) BIT_TYPE(u8, nr)
#define BIT_U16(nr) BIT_TYPE(u16, nr)
diff --git a/lib/tests/test_bits.c b/lib/tests/test_bits.c
index ab88e50d2edf..55be8230f9e7 100644
--- a/lib/tests/test_bits.c
+++ b/lib/tests/test_bits.c
@@ -9,20 +9,20 @@
#define assert_type(t, x) _Generic(x, t: x, default: 0)
-static_assert(assert_type(u8, BIT_U8(0)) == 1u);
-static_assert(assert_type(u16, BIT_U16(0)) == 1u);
+static_assert(assert_type(unsigned int, BIT_U8(0)) == 1u);
+static_assert(assert_type(unsigned int, BIT_U16(0)) == 1u);
static_assert(assert_type(u32, BIT_U32(0)) == 1u);
static_assert(assert_type(u64, BIT_U64(0)) == 1ull);
-static_assert(assert_type(u8, BIT_U8(7)) == 0x80u);
-static_assert(assert_type(u16, BIT_U16(15)) == 0x8000u);
+static_assert(assert_type(unsigned int, BIT_U8(7)) == 0x80u);
+static_assert(assert_type(unsigned int, BIT_U16(15)) == 0x8000u);
static_assert(assert_type(u32, BIT_U32(31)) == 0x80000000u);
static_assert(assert_type(u64, BIT_U64(63)) == 0x8000000000000000ull);
static_assert(assert_type(unsigned long, GENMASK(31, 0)) == U32_MAX);
static_assert(assert_type(unsigned long long, GENMASK_ULL(63, 0)) == U64_MAX);
-static_assert(assert_type(u8, GENMASK_U8(7, 0)) == U8_MAX);
-static_assert(assert_type(u16, GENMASK_U16(15, 0)) == U16_MAX);
+static_assert(assert_type(unsigned int, GENMASK_U8(7, 0)) == U8_MAX);
+static_assert(assert_type(unsigned int, GENMASK_U16(15, 0)) == U16_MAX);
static_assert(assert_type(u32, GENMASK_U32(31, 0)) == U32_MAX);
static_assert(assert_type(u64, GENMASK_U64(63, 0)) == U64_MAX);
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx()
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (8 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 09/14] bits: Change BIT_U8/16() and GENMASK_U8/16() to have unsigned values david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-02-08 3:31 ` Yury Norov
2026-01-21 14:57 ` [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() david.laight.linux
` (3 subsequent siblings)
13 siblings, 1 reply; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
The assembler only supports one type of signed integers, so expressions
using BITS_PER_LONG (etc) cannot be guaranteed to be correct.
Use ((2 << (h)) - (1 << (l))) for all assembler GENMASK() expansions and
add definitions of BIT_Uxx() as (1 << (nr)).
Note that 64bit results are (probably) only correct for 64bit builds
and 128bits results will never be valid.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
include/linux/bits.h | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/include/linux/bits.h b/include/linux/bits.h
index 23bc94815569..43631a334314 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -19,14 +19,6 @@
*/
#if !defined(__ASSEMBLY__)
-/*
- * Missing asm support
- *
- * GENMASK_U*() and BIT_U*() depend on BITS_PER_TYPE() which relies on sizeof(),
- * something not available in asm. Nevertheless, fixed width integers is a C
- * concept. Assembly code can rely on the long and long long versions instead.
- */
-
#include <linux/build_bug.h>
#include <linux/compiler.h>
#include <linux/overflow.h>
@@ -46,6 +38,7 @@
#define GENMASK_TYPE(t, h, l) \
((unsigned int)GENMASK_INPUT_CHECK(h, l) + \
((t)-1 << (l) & (t)-1 >> (BITS_PER_TYPE(t) - 1 - (h))))
+#endif
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
#define GENMASK_ULL(h, l) GENMASK_TYPE(unsigned long long, h, l)
@@ -56,9 +49,10 @@
#define GENMASK_U64(h, l) GENMASK_TYPE(u64, h, l)
#define GENMASK_U128(h, l) GENMASK_TYPE(u128, h, l)
+#if !defined(__ASSEMBLY__)
/*
- * Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE(). The
- * following examples generate compiler warnings due to -Wshift-count-overflow:
+ * Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE().
+ * The following examples generate compiler warnings from BIT_INPUT_CHECK().
*
* - BIT_U8(8)
* - BIT_U32(-1)
@@ -68,21 +62,28 @@
BUILD_BUG_ON_ZERO(const_true((nr) >= BITS_PER_TYPE(type)))
#define BIT_TYPE(type, nr) ((unsigned int)BIT_INPUT_CHECK(type, nr) + ((type)1 << (nr)))
+#endif /* defined(__ASSEMBLY__) */
#define BIT_U8(nr) BIT_TYPE(u8, nr)
#define BIT_U16(nr) BIT_TYPE(u16, nr)
#define BIT_U32(nr) BIT_TYPE(u32, nr)
#define BIT_U64(nr) BIT_TYPE(u64, nr)
-#else /* defined(__ASSEMBLY__) */
+#if defined(__ASSEMBLY__)
/*
- * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
- * disable the input check if that is the case.
+ * The assmebler only supports one size of signed integer rather than
+ * the fixed width integer types of C.
+ * There is also no method for reported invalid input.
+ * Error in .h files will usually be picked up when compiled into C files.
+ *
+ * Define type-size agnostic definitions that generate the correct value
+ * provided it can be represented by the assembler.
*/
-#define GENMASK(h, l) __GENMASK(h, l)
-#define GENMASK_ULL(h, l) __GENMASK_ULL(h, l)
-#endif /* !defined(__ASSEMBLY__) */
+#define GENMASK_TYPE(t, h, l) ((2 << (h)) - (1 << (l)))
+#define BIT_TYPE(type, nr) (1 << (nr))
+
+#endif /* defined(__ASSEMBLY__) */
#endif /* __LINUX_BITS_H */
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx()
2026-01-21 14:57 ` [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx() david.laight.linux
@ 2026-02-08 3:31 ` Yury Norov
2026-02-08 11:42 ` David Laight
0 siblings, 1 reply; 56+ messages in thread
From: Yury Norov @ 2026-02-08 3:31 UTC (permalink / raw)
To: david.laight.linux
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Wed, Jan 21, 2026 at 02:57:27PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> The assembler only supports one type of signed integers, so expressions
> using BITS_PER_LONG (etc) cannot be guaranteed to be correct.
>
> Use ((2 << (h)) - (1 << (l))) for all assembler GENMASK() expansions and
> add definitions of BIT_Uxx() as (1 << (nr)).
>
> Note that 64bit results are (probably) only correct for 64bit builds
> and 128bits results will never be valid.
And this important note will sink in git history.
> Signed-off-by: David Laight <david.laight.linux@gmail.com>
This has been discussed in details when those GENMASK_Uxx() were
introduced. Assembler doesn't support C types, and can't provide any
guarantees. It may only confuse readers when they see something like
GENMASK_U8() in the assembler code, and there's nothing on behalf of
that declaration to enforce the limitation.
That's why we didn't add fake C types support in the assembler. Unless
we find a way to enforce C types capacity in assembler(s), let's keep
those macros C-only.
Thanks,
Yury
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx()
2026-02-08 3:31 ` Yury Norov
@ 2026-02-08 11:42 ` David Laight
2026-02-08 21:20 ` Yury Norov
0 siblings, 1 reply; 56+ messages in thread
From: David Laight @ 2026-02-08 11:42 UTC (permalink / raw)
To: Yury Norov
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Sat, 7 Feb 2026 22:31:34 -0500
Yury Norov <ynorov@nvidia.com> wrote:
> On Wed, Jan 21, 2026 at 02:57:27PM +0000, david.laight.linux@gmail.com wrote:
> > From: David Laight <david.laight.linux@gmail.com>
> >
> > The assembler only supports one type of signed integers, so expressions
> > using BITS_PER_LONG (etc) cannot be guaranteed to be correct.
> >
> > Use ((2 << (h)) - (1 << (l))) for all assembler GENMASK() expansions and
> > add definitions of BIT_Uxx() as (1 << (nr)).
> >
> > Note that 64bit results are (probably) only correct for 64bit builds
> > and 128bits results will never be valid.
>
> And this important note will sink in git history.
At least it isn't only in the email archives.
I can put it in a comment.
> > Signed-off-by: David Laight <david.laight.linux@gmail.com>
>
> This has been discussed in details when those GENMASK_Uxx() were
> introduced. Assembler doesn't support C types, and can't provide any
> guarantees. It may only confuse readers when they see something like
> GENMASK_U8() in the assembler code, and there's nothing on behalf of
> that declaration to enforce the limitation.
It won't be in asm code, the asm code will be expanding a constant
from a C header file.
> That's why we didn't add fake C types support in the assembler. Unless
> we find a way to enforce C types capacity in assembler(s), let's keep
> those macros C-only.
But GENMASK_ULL() was already there and would generate invalid values
(for small values) on 32bit.
The only reason for defining these for assembler is so that .h files
that use the definitions can be used in .S files.
As soon as any of the BIT_Unn() get used the asm code is likely to
try to expand them.
David
>
> Thanks,
> Yury
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx()
2026-02-08 11:42 ` David Laight
@ 2026-02-08 21:20 ` Yury Norov
2026-02-08 22:27 ` David Laight
0 siblings, 1 reply; 56+ messages in thread
From: Yury Norov @ 2026-02-08 21:20 UTC (permalink / raw)
To: David Laight
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Sun, Feb 08, 2026 at 11:42:14AM +0000, David Laight wrote:
> On Sat, 7 Feb 2026 22:31:34 -0500
> Yury Norov <ynorov@nvidia.com> wrote:
>
> > On Wed, Jan 21, 2026 at 02:57:27PM +0000, david.laight.linux@gmail.com wrote:
> > > From: David Laight <david.laight.linux@gmail.com>
> > >
> > > The assembler only supports one type of signed integers, so expressions
> > > using BITS_PER_LONG (etc) cannot be guaranteed to be correct.
> > >
> > > Use ((2 << (h)) - (1 << (l))) for all assembler GENMASK() expansions and
> > > add definitions of BIT_Uxx() as (1 << (nr)).
> > >
> > > Note that 64bit results are (probably) only correct for 64bit builds
> > > and 128bits results will never be valid.
> >
> > And this important note will sink in git history.
>
> At least it isn't only in the email archives.
> I can put it in a comment.
>
> > > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> >
> > This has been discussed in details when those GENMASK_Uxx() were
> > introduced. Assembler doesn't support C types, and can't provide any
> > guarantees. It may only confuse readers when they see something like
> > GENMASK_U8() in the assembler code, and there's nothing on behalf of
> > that declaration to enforce the limitation.
>
> It won't be in asm code, the asm code will be expanding a constant
> from a C header file.
It can be included and preprocessed well in any .S file:
#define GENMASK_TYPE(t, h,l) ((2 << (h)) - (1 << (l)))
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, (h), (l))
.section .rodata
fmt:
.string "GENMASK(63,60) = 0x%016llx\n"
.text
.globl main
.type main, @function
main:
push %rbp
mov %rsp, %rbp
lea fmt(%rip), %rdi
mov $GENMASK(63,60), %rsi
xor %rax, %rax
call printf@PLT
mov $0, %eax
pop %rbp
ret
In C this doesn't work at all as it throws overflow. It doesn't even
work in asm volatile section.
> > That's why we didn't add fake C types support in the assembler. Unless
> > we find a way to enforce C types capacity in assembler(s), let's keep
> > those macros C-only.
>
> But GENMASK_ULL() was already there and would generate invalid values
> (for small values) on 32bit.
You continuously repeat that GENMASK_ULL() generates wrong values, but
never submitted a fix.
Anyways, if you think GENMASK_ULL() is not needed in assembler, it's
even harder to advocate fixed-type flavors.
> The only reason for defining these for assembler is so that .h files
> that use the definitions can be used in .S files.
> As soon as any of the BIT_Unn() get used the asm code is likely to
> try to expand them.
The only reason for fixed-type GENMASK() and BIT() is strict
parameters checking. This is not possible in assembler.
Thanks,
Yury
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx()
2026-02-08 21:20 ` Yury Norov
@ 2026-02-08 22:27 ` David Laight
0 siblings, 0 replies; 56+ messages in thread
From: David Laight @ 2026-02-08 22:27 UTC (permalink / raw)
To: Yury Norov
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Sun, 8 Feb 2026 16:20:45 -0500
Yury Norov <ynorov@nvidia.com> wrote:
> On Sun, Feb 08, 2026 at 11:42:14AM +0000, David Laight wrote:
> > On Sat, 7 Feb 2026 22:31:34 -0500
> > Yury Norov <ynorov@nvidia.com> wrote:
> >
> > > On Wed, Jan 21, 2026 at 02:57:27PM +0000, david.laight.linux@gmail.com wrote:
> > > > From: David Laight <david.laight.linux@gmail.com>
> > > >
> > > > The assembler only supports one type of signed integers, so expressions
> > > > using BITS_PER_LONG (etc) cannot be guaranteed to be correct.
> > > >
> > > > Use ((2 << (h)) - (1 << (l))) for all assembler GENMASK() expansions and
> > > > add definitions of BIT_Uxx() as (1 << (nr)).
> > > >
> > > > Note that 64bit results are (probably) only correct for 64bit builds
> > > > and 128bits results will never be valid.
> > >
> > > And this important note will sink in git history.
> >
> > At least it isn't only in the email archives.
> > I can put it in a comment.
> >
> > > > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> > >
> > > This has been discussed in details when those GENMASK_Uxx() were
> > > introduced. Assembler doesn't support C types, and can't provide any
> > > guarantees. It may only confuse readers when they see something like
> > > GENMASK_U8() in the assembler code, and there's nothing on behalf of
> > > that declaration to enforce the limitation.
> >
> > It won't be in asm code, the asm code will be expanding a constant
> > from a C header file.
>
> It can be included and preprocessed well in any .S file:
>
> #define GENMASK_TYPE(t, h,l) ((2 << (h)) - (1 << (l)))
> #define GENMASK(h, l) GENMASK_TYPE(unsigned long, (h), (l))
>
> .section .rodata
> fmt:
> .string "GENMASK(63,60) = 0x%016llx\n"
>
> .text
> .globl main
> .type main, @function
>
> main:
> push %rbp
> mov %rsp, %rbp
>
> lea fmt(%rip), %rdi
> mov $GENMASK(63,60), %rsi
> xor %rax, %rax
> call printf@PLT
>
> mov $0, %eax
> pop %rbp
> ret
>
> In C this doesn't work at all as it throws overflow. It doesn't even
> work in asm volatile section.
Indeed - that I'm not trying to use that expression in C.
Although it will work for non-constants.
For constants you'd have to use ((1 << hi) - 1) * 2) + 1.
While I'm pretty sure the compiler will convert it to the former, both
generate worse code in some corner cases.
The issue at the moment is that you get these definitions from uapi/linux/bits.h
#define __GENMASK(h, l) (((~_UL(0)) << (l)) & (~_UL(0) >> (__BITS_PER_LONG - 1 - (h))))
#define __GENMASK_ULL(h, l) (((~_ULL(0)) << (l)) & (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h))))
For .S files both _UL() and _ULL() are null, so these are:
#define __GENMASK(h, l) (((~0) << (l)) & (~0 >> (__BITS_PER_LONG - 1 - (h))))
#define __GENMASK_ULL(h, l) (((~0) << (l)) & (~0 >> (__BITS_PER_LONG_LONG - 1 - (h))))
Which makes them identical except for the two constants.
On 32bit builds the two constants are different which means that while __GENMASK(5, 2)
and __GENMASK_ULL(5,2) should have the same value they may not (depending exactly
how the assembler evaluates constant expressions).
Assuming that either __BITS_PER_LONG or __BITS_PER_LONG_LONG has anything to do
with the number of bits in the assembler's expression evaluator doesn't seem
right at all.
David
>
> > > That's why we didn't add fake C types support in the assembler. Unless
> > > we find a way to enforce C types capacity in assembler(s), let's keep
> > > those macros C-only.
> >
> > But GENMASK_ULL() was already there and would generate invalid values
> > (for small values) on 32bit.
>
> You continuously repeat that GENMASK_ULL() generates wrong values, but
> never submitted a fix.
>
> Anyways, if you think GENMASK_ULL() is not needed in assembler, it's
> even harder to advocate fixed-type flavors.
>
> > The only reason for defining these for assembler is so that .h files
> > that use the definitions can be used in .S files.
> > As soon as any of the BIT_Unn() get used the asm code is likely to
> > try to expand them.
>
> The only reason for fixed-type GENMASK() and BIT() is strict
> parameters checking. This is not possible in assembler.
>
> Thanks,
> Yury
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (9 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 10/14] bits: Fix assmebler expansions of GENMASK_Uxx() and BIT_Uxx() david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-01-21 18:43 ` Vincent Mailhol
` (2 more replies)
2026-01-21 14:57 ` [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h david.laight.linux
` (2 subsequent siblings)
13 siblings, 3 replies; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
The current checks in GENMASK/BIT (eg reversed high/low) only work
for 'integer constant expressions' not 'compile-time constants'.
This is true for const_true() and -Wshift-count-overflow/negative.
While compile-time constants may be unusual, they can happen through
function inlining.
This isn't too bad with gcc, but if clang detects a negative/over-large
shift it treats it as 'undefined behaviour' and silently discards all
code that would use the result, so:
int f(u32 x) {int n = 32; return x >> n; }
generates a function that just contains a 'return' instruction.
If 'n' was a variable that happened to be 32, most modern cpu mask
the count - so would return 'x', some might return 0.
Add extra checks for arguments that pass __builtin_constant_p()
but are not 'integer constant expressions.
__builtin_choose_expr() isn't strong enough to allow
_Static_assert() or ({ ... }) in the other branch so non-standard
schemes are used to report the errors.
To reduce pre-processor bloat the checks are only enabled for W=c
(implied by W=1) builds (where they are errors).
Update the unit tests to match.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
include/linux/bits.h | 45 +++++++++++++++++++++++++++++++++----------
lib/tests/test_bits.c | 34 +++++++++++++++++++-------------
2 files changed, 56 insertions(+), 23 deletions(-)
diff --git a/include/linux/bits.h b/include/linux/bits.h
index 43631a334314..0f559038981d 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -23,20 +23,35 @@
#include <linux/compiler.h>
#include <linux/overflow.h>
-#define GENMASK_INPUT_CHECK(h, l) BUILD_BUG_ON_ZERO(const_true((l) > (h)))
+#ifndef KBUILD_EXTRA_WARNc
+#define GENMASK_INPUT_CHECK(h, l, width) 0
+#else
+int GENMASK_INPUT_CHECK_FAIL(void) __compiletime_error("Invalid bit numbers");
+#define GENMASK_INPUT_CHECK(h, l, width) \
+ (__builtin_choose_expr(__is_constexpr((l) > (h)), \
+ sizeof(struct { char low_bit_greater_than_high[-((l) > (h))];}), \
+ __builtin_constant_p((l) | (h)) && \
+ ((l) < 0 || (l) > (h) || (h) >= width) && \
+ GENMASK_INPUT_CHECK_FAIL()))
+#endif
/*
- * Generate a mask for the specified type @t. Additional checks are made to
- * guarantee the value returned fits in that type, relying on
- * -Wshift-count-overflow compiler check to detect incompatible arguments.
+ * Generate a mask for the specified type @t.
+ * Checks are made to guarantee the value returned fits in that type.
+ * The compiler's -Wshift-count-overflow/negative check detects invalid values
+ * from 'constant integer expressions' but not other compile time constants.
+ * Clang treats out of value constants as 'undefined behaviour' and stops
+ * generating code - so explicit checks are needed.
+ * Neither BUILD_BUG() nor BUILD_BUG_ON_ZERO() can be used.
+ *
* For example, all these create build errors or warnings:
*
* - GENMASK(15, 20): wrong argument order
* - GENMASK(72, 15): doesn't fit unsigned long
* - GENMASK_U32(33, 15): doesn't fit in a u32
*/
-#define GENMASK_TYPE(t, h, l) \
- ((unsigned int)GENMASK_INPUT_CHECK(h, l) + \
+#define GENMASK_TYPE(t, h, l) \
+ ((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
((t)-1 << (l) & (t)-1 >> (BITS_PER_TYPE(t) - 1 - (h))))
#endif
@@ -52,16 +67,26 @@
#if !defined(__ASSEMBLY__)
/*
* Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE().
- * The following examples generate compiler warnings from BIT_INPUT_CHECK().
+ * The following examples generate compiler errors from BIT_INPUT_CHECK().
*
* - BIT_U8(8)
* - BIT_U32(-1)
* - BIT_U32(40)
*/
-#define BIT_INPUT_CHECK(type, nr) \
- BUILD_BUG_ON_ZERO(const_true((nr) >= BITS_PER_TYPE(type)))
-#define BIT_TYPE(type, nr) ((unsigned int)BIT_INPUT_CHECK(type, nr) + ((type)1 << (nr)))
+#ifndef KBUILD_EXTRA_WARNc
+#define BIT_INPUT_CHECK(nr, width) 0
+#else
+int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
+#define BIT_INPUT_CHECK(nr, width) \
+ (__builtin_choose_expr(__is_constexpr(nr), \
+ sizeof(struct { char bit_number_too_big[-((nr) >= (width))];}), \
+ __builtin_constant_p(nr) && ((nr) < 0 || (nr) >= width) && \
+ BIT_INPUT_CHECK_FAIL()))
+#endif
+
+#define BIT_TYPE(type, nr) \
+ ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
#endif /* defined(__ASSEMBLY__) */
#define BIT_U8(nr) BIT_TYPE(u8, nr)
diff --git a/lib/tests/test_bits.c b/lib/tests/test_bits.c
index 55be8230f9e7..36eb4661e78b 100644
--- a/lib/tests/test_bits.c
+++ b/lib/tests/test_bits.c
@@ -3,6 +3,8 @@
* Test cases for functions and macros in bits.h
*/
+#define KBUILD_EXTRA_WARNc 1
+
#include <kunit/test.h>
#include <linux/bits.h>
#include <linux/types.h>
@@ -118,24 +120,30 @@ static void genmask_u128_test(struct kunit *test)
static void genmask_input_check_test(struct kunit *test)
{
- unsigned int x, y;
- int z, w;
+ unsigned int x = 1, y = 2;
+ int z = 1, w = 2;
+
+ OPTIMIZER_HIDE_VAR(x);
+ OPTIMIZER_HIDE_VAR(y);
+ OPTIMIZER_HIDE_VAR(z);
+ OPTIMIZER_HIDE_VAR(w);
/* Unknown input */
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, 0));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, x));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, y));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, 0, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, x, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, y, 32));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, 0));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, z));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, w));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, 0, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, z, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, w, 32));
/* Valid input */
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(1, 1));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(39, 21));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(100, 80));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(110, 65));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(127, 0));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(1, 1, 32));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(39, 21, 64));
+
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(100, 80, 128));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(110, 65, 128));
+ KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(127, 0, 128));
}
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-21 14:57 ` [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() david.laight.linux
@ 2026-01-21 18:43 ` Vincent Mailhol
2026-01-21 19:14 ` David Laight
2026-01-22 1:11 ` kernel test robot
2026-01-22 4:41 ` kernel test robot
2 siblings, 1 reply; 56+ messages in thread
From: Vincent Mailhol @ 2026-01-21 18:43 UTC (permalink / raw)
To: david.laight.linux
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Andy Shevchenko, Kees Cook, Andrew Morton
On 21/01/2026 at 15:57, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> The current checks in GENMASK/BIT (eg reversed high/low) only work
> for 'integer constant expressions' not 'compile-time constants'.
> This is true for const_true() and -Wshift-count-overflow/negative.
> While compile-time constants may be unusual, they can happen through
> function inlining.
Did those new checks actually found any real problem in the code? This
adds a lot of complexity so I am not sure whether this is a winning
trade-off.
> This isn't too bad with gcc, but if clang detects a negative/over-large
> shift it treats it as 'undefined behaviour' and silently discards all
> code that would use the result, so:
> int f(u32 x) {int n = 32; return x >> n; }
> generates a function that just contains a 'return' instruction.
> If 'n' was a variable that happened to be 32, most modern cpu mask
> the count - so would return 'x', some might return 0.
But then, you only solve that shift problem for GENMASK() and
BIT(). Any other usage of the left/right shifts are not diagnosed
unless your check get copy pasted all over the place.
I think that such a check belongs to a static analyzer. Speaking of
which:
$ cat test.c
typedef unsigned int u32;
static int f(u32 x) {int n = 32; return x >> n; }
$ sparse test.c
test.c:2:46: warning: shift too big (32) for type unsigned int$ cat test.c
So here, I would rather keep relying on sparse rather that introducing
the W=c logic and all that macro complexity.
Yours sincerely,
Vincent Mailhol
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-21 18:43 ` Vincent Mailhol
@ 2026-01-21 19:14 ` David Laight
0 siblings, 0 replies; 56+ messages in thread
From: David Laight @ 2026-01-21 19:14 UTC (permalink / raw)
To: Vincent Mailhol
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Andy Shevchenko, Kees Cook, Andrew Morton
On Wed, 21 Jan 2026 19:43:07 +0100
Vincent Mailhol <mailhol@kernel.org> wrote:
> On 21/01/2026 at 15:57, david.laight.linux@gmail.com wrote:
> > From: David Laight <david.laight.linux@gmail.com>
> >
> > The current checks in GENMASK/BIT (eg reversed high/low) only work
> > for 'integer constant expressions' not 'compile-time constants'.
> > This is true for const_true() and -Wshift-count-overflow/negative.
> > While compile-time constants may be unusual, they can happen through
> > function inlining.
>
> Did those new checks actually found any real problem in the code? This
> adds a lot of complexity so I am not sure whether this is a winning
> trade-off.
Not in an x86-64 allmodconfig build.
They might in a 32bit one where there have definitely been issues.
>
> > This isn't too bad with gcc, but if clang detects a negative/over-large
> > shift it treats it as 'undefined behaviour' and silently discards all
> > code that would use the result, so:
> > int f(u32 x) {int n = 32; return x >> n; }
> > generates a function that just contains a 'return' instruction.
> > If 'n' was a variable that happened to be 32, most modern cpu mask
> > the count - so would return 'x', some might return 0.
>
> But then, you only solve that shift problem for GENMASK() and
> BIT(). Any other usage of the left/right shifts are not diagnosed
> unless your check get copy pasted all over the place.
>
> I think that such a check belongs to a static analyzer. Speaking of
> which:
>
> $ cat test.c
> typedef unsigned int u32;
> static int f(u32 x) {int n = 32; return x >> n; }
>
> $ sparse test.c
> test.c:2:46: warning: shift too big (32) for type unsigned int$ cat test.c
>
> So here, I would rather keep relying on sparse rather that introducing
> the W=c logic and all that macro complexity.
I suspect the compiler test will find more than sparse.
I liked getting that to work, but maybe it is OTT.
But the W=c is more generally useful.
As well as removing all the compile-time tests from GENMASK() and
(in another patch FIELD_PREP()) which really do bloat the .i file,
I'd like to add some new tests to min/max/clamp to try to get rid
of the more dodgy (and likely buggy) cases without breaking
everyone's build - just failing the W=1 builds is better.
Using a separate flag means you can use W=ce to stop the build,
doing a W=1e build is hopeless.
David
>
>
> Yours sincerely,
> Vincent Mailhol
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-21 14:57 ` [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() david.laight.linux
2026-01-21 18:43 ` Vincent Mailhol
@ 2026-01-22 1:11 ` kernel test robot
2026-01-22 10:25 ` David Laight
2026-01-22 4:41 ` kernel test robot
2 siblings, 1 reply; 56+ messages in thread
From: kernel test robot @ 2026-01-22 1:11 UTC (permalink / raw)
To: david.laight.linux, Nathan Chancellor, Greg Kroah-Hartman,
Thomas Gleixner, Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers,
Arnd Bergmann, linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton
Cc: oe-kbuild-all, Linux Memory Management List, David Laight
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on next-20260120]
url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
base: next-20260120
patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com
patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
config: s390-randconfig-001-20260122 (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601220829.MgTMeqqN-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from arch/s390/include/asm/bug.h:60,
from include/linux/bug.h:5,
from include/linux/mmdebug.h:5,
from arch/s390/include/asm/cmpxchg.h:11,
from arch/s390/include/asm/atomic.h:16,
from include/linux/atomic.h:7,
from include/asm-generic/bitops/atomic.h:5,
from arch/s390/include/asm/bitops.h:75,
from include/linux/bitops.h:67,
from include/linux/kernel.h:23,
from net/core/page_pool.c:10:
In function 'netmem_clear_pp_magic',
inlined from 'page_pool_clear_pp_info' at net/core/page_pool.c:721:2:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/asm-generic/bug.h:120:25: note: in definition of macro 'WARN_ON_ONCE'
int __ret_warn_on = !!(condition); \
^~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:18:52: note: in expansion of macro 'PP_DMA_INDEX_MASK'
WARN_ON_ONCE(netmem_to_nmdesc(netmem)->pp_magic & PP_DMA_INDEX_MASK);
^~~~~~~~~~~~~~~~~
--
In file included from include/linux/bitops.h:6,
from arch/s390/include/asm/machine.h:25,
from arch/s390/include/asm/lowcore.h:13,
from arch/s390/include/asm/current.h:13,
from arch/s390/include/asm/preempt.h:5,
from include/linux/preempt.h:79,
from arch/s390/include/asm/timex.h:13,
from include/linux/timex.h:67,
from include/linux/time32.h:13,
from include/linux/time.h:60,
from include/linux/stat.h:19,
from include/linux/module.h:13,
from net/core/skbuff.c:37:
In function 'netmem_get_pp_magic',
inlined from 'netmem_is_pp' at net/core/netmem_priv.h:25:10,
inlined from 'napi_pp_put_page' at net/core/skbuff.c:1027:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:8:47: note: in expansion of macro 'PP_DMA_INDEX_MASK'
return netmem_to_nmdesc(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
^~~~~~~~~~~~~~~~~
In function 'netmem_is_pp',
inlined from 'napi_pp_put_page' at net/core/skbuff.c:1027:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
include/linux/mm.h:4650:25: note: in expansion of macro 'PP_DMA_INDEX_MASK'
#define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
^~~~~~~~~~~~~~~~~
net/core/netmem_priv.h:25:40: note: in expansion of macro 'PP_MAGIC_MASK'
return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
^~~~~~~~~~~~~
In function 'netmem_get_pp_magic',
inlined from 'netmem_is_pp' at net/core/netmem_priv.h:25:10,
inlined from 'napi_pp_put_page' at net/core/skbuff.c:1027:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:8:47: note: in expansion of macro 'PP_DMA_INDEX_MASK'
return netmem_to_nmdesc(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
^~~~~~~~~~~~~~~~~
In function 'netmem_is_pp',
inlined from 'napi_pp_put_page' at net/core/skbuff.c:1027:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
include/linux/mm.h:4650:25: note: in expansion of macro 'PP_DMA_INDEX_MASK'
#define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
^~~~~~~~~~~~~~~~~
net/core/netmem_priv.h:25:40: note: in expansion of macro 'PP_MAGIC_MASK'
return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
^~~~~~~~~~~~~
In function 'netmem_get_pp_magic',
inlined from 'netmem_is_pp' at net/core/netmem_priv.h:25:10,
inlined from 'skb_pp_frag_ref' at net/core/skbuff.c:1067:7,
inlined from 'skb_try_coalesce' at net/core/skbuff.c:6203:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:8:47: note: in expansion of macro 'PP_DMA_INDEX_MASK'
return netmem_to_nmdesc(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
^~~~~~~~~~~~~~~~~
In function 'netmem_is_pp',
inlined from 'skb_pp_frag_ref' at net/core/skbuff.c:1067:7,
inlined from 'skb_try_coalesce' at net/core/skbuff.c:6203:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
include/linux/mm.h:4650:25: note: in expansion of macro 'PP_DMA_INDEX_MASK'
#define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
^~~~~~~~~~~~~~~~~
net/core/netmem_priv.h:25:40: note: in expansion of macro 'PP_MAGIC_MASK'
return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
^~~~~~~~~~~~~
In function 'netmem_get_pp_magic',
inlined from 'netmem_is_pp' at net/core/netmem_priv.h:25:10,
inlined from 'skb_pp_frag_ref' at net/core/skbuff.c:1067:7,
inlined from 'skb_try_coalesce' at net/core/skbuff.c:6203:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
net/core/netmem_priv.h:8:47: note: in expansion of macro 'PP_DMA_INDEX_MASK'
return netmem_to_nmdesc(netmem)->pp_magic & ~PP_DMA_INDEX_MASK;
^~~~~~~~~~~~~~~~~
In function 'netmem_is_pp',
inlined from 'skb_pp_frag_ref' at net/core/skbuff.c:1067:7,
inlined from 'skb_try_coalesce' at net/core/skbuff.c:6203:6:
>> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
GENMASK_INPUT_CHECK_FAIL()))
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:54:17: note: in expansion of macro 'GENMASK_INPUT_CHECK'
((unsigned int)GENMASK_INPUT_CHECK(h, l, BITS_PER_TYPE(t)) + \
^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:58:24: note: in expansion of macro 'GENMASK_TYPE'
#define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l)
^~~~~~~~~~~~
include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
^~~~~~~
include/linux/mm.h:4650:25: note: in expansion of macro 'PP_DMA_INDEX_MASK'
#define PP_MAGIC_MASK ~(PP_DMA_INDEX_MASK | 0x3UL)
^~~~~~~~~~~~~~~~~
net/core/netmem_priv.h:25:40: note: in expansion of macro 'PP_MAGIC_MASK'
return (netmem_get_pp_magic(netmem) & PP_MAGIC_MASK) == PP_SIGNATURE;
^~~~~~~~~~~~~
vim +/GENMASK_INPUT_CHECK_FAIL +35 include/linux/bits.h
25
26 #ifndef KBUILD_EXTRA_WARNc
27 #define GENMASK_INPUT_CHECK(h, l, width) 0
28 #else
29 int GENMASK_INPUT_CHECK_FAIL(void) __compiletime_error("Invalid bit numbers");
30 #define GENMASK_INPUT_CHECK(h, l, width) \
31 (__builtin_choose_expr(__is_constexpr((l) > (h)), \
32 sizeof(struct { char low_bit_greater_than_high[-((l) > (h))];}), \
33 __builtin_constant_p((l) | (h)) && \
34 ((l) < 0 || (l) > (h) || (h) >= width) && \
> 35 GENMASK_INPUT_CHECK_FAIL()))
36 #endif
37
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-22 1:11 ` kernel test robot
@ 2026-01-22 10:25 ` David Laight
2026-01-22 20:10 ` David Laight
0 siblings, 1 reply; 56+ messages in thread
From: David Laight @ 2026-01-22 10:25 UTC (permalink / raw)
To: kernel test robot
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton,
oe-kbuild-all, Linux Memory Management List
On Thu, 22 Jan 2026 09:11:53 +0800
kernel test robot <lkp@intel.com> wrote:
> Hi,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on next-20260120]
>
> url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
> base: next-20260120
> patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com
> patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
> config: s390-randconfig-001-20260122 (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/config)
> compiler: s390-linux-gcc (GCC) 8.5.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202601220829.MgTMeqqN-lkp@intel.com/
>
> All errors (new ones prefixed by >>):
>
> In file included from arch/s390/include/asm/bug.h:60,
> from include/linux/bug.h:5,
> from include/linux/mmdebug.h:5,
> from arch/s390/include/asm/cmpxchg.h:11,
> from arch/s390/include/asm/atomic.h:16,
> from include/linux/atomic.h:7,
> from include/asm-generic/bitops/atomic.h:5,
> from arch/s390/include/asm/bitops.h:75,
> from include/linux/bitops.h:67,
> from include/linux/kernel.h:23,
> from net/core/page_pool.c:10:
> In function 'netmem_clear_pp_magic',
> inlined from 'page_pool_clear_pp_info' at net/core/page_pool.c:721:2:
> >> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
...
> include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
> #define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
This might be a real bug.
The bit of mm.h is:
#define PP_DMA_INDEX_SHIFT (1 + __fls(PP_SIGNATURE - POISON_POINTER_DELTA))
#if POISON_POINTER_DELTA > 0
/* PP_SIGNATURE includes POISON_POINTER_DELTA, so limit the size of the DMA
* index to not overlap with that if set
*/
#define PP_DMA_INDEX_BITS MIN(32, __ffs(POISON_POINTER_DELTA) - PP_DMA_INDEX_SHIFT)
#else
/* Use the lowest bit of PAGE_OFFSET if there's at least 8 bits available; see above */
#define PP_DMA_INDEX_MIN_OFFSET (1 << (PP_DMA_INDEX_SHIFT + 8))
#define PP_DMA_INDEX_BITS ((__builtin_constant_p(PAGE_OFFSET) && \
PAGE_OFFSET >= PP_DMA_INDEX_MIN_OFFSET && \
!(PAGE_OFFSET & (PP_DMA_INDEX_MIN_OFFSET - 1))) ? \
MIN(32, __ffs(PAGE_OFFSET) - PP_DMA_INDEX_SHIFT) : 0)
#endif
#define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
PP_DMA_INDEX_SHIFT)
I've no idea what the values are, but the 'hi' bit number must exceed that
of 'long'.
The __ffs() probably stop it being an 'integer constant expression'
making it just a 'compile time constant' - which I added a test for.
David
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-22 10:25 ` David Laight
@ 2026-01-22 20:10 ` David Laight
0 siblings, 0 replies; 56+ messages in thread
From: David Laight @ 2026-01-22 20:10 UTC (permalink / raw)
To: kernel test robot
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton,
oe-kbuild-all, Linux Memory Management List
On Thu, 22 Jan 2026 10:25:54 +0000
David Laight <david.laight.linux@gmail.com> wrote:
> On Thu, 22 Jan 2026 09:11:53 +0800
> kernel test robot <lkp@intel.com> wrote:
>
> > Hi,
> >
> > kernel test robot noticed the following build errors:
> >
> > [auto build test ERROR on next-20260120]
> >
> > url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
> > base: next-20260120
> > patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com
> > patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
> > config: s390-randconfig-001-20260122 (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/config)
> > compiler: s390-linux-gcc (GCC) 8.5.0
> > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220829.MgTMeqqN-lkp@intel.com/reproduce)
> >
> > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > the same patch/commit), kindly add following tags
> > | Reported-by: kernel test robot <lkp@intel.com>
> > | Closes: https://lore.kernel.org/oe-kbuild-all/202601220829.MgTMeqqN-lkp@intel.com/
> >
> > All errors (new ones prefixed by >>):
> >
> > In file included from arch/s390/include/asm/bug.h:60,
> > from include/linux/bug.h:5,
> > from include/linux/mmdebug.h:5,
> > from arch/s390/include/asm/cmpxchg.h:11,
> > from arch/s390/include/asm/atomic.h:16,
> > from include/linux/atomic.h:7,
> > from include/asm-generic/bitops/atomic.h:5,
> > from arch/s390/include/asm/bitops.h:75,
> > from include/linux/bitops.h:67,
> > from include/linux/kernel.h:23,
> > from net/core/page_pool.c:10:
> > In function 'netmem_clear_pp_magic',
> > inlined from 'page_pool_clear_pp_info' at net/core/page_pool.c:721:2:
> > >> include/linux/bits.h:35:4: error: call to 'GENMASK_INPUT_CHECK_FAIL' declared with attribute error: Invalid bit numbers
> ...
> > include/linux/mm.h:4641:27: note: in expansion of macro 'GENMASK'
> > #define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
>
> This might be a real bug.
>
> The bit of mm.h is:
>
> #define PP_DMA_INDEX_SHIFT (1 + __fls(PP_SIGNATURE - POISON_POINTER_DELTA))
> #if POISON_POINTER_DELTA > 0
> /* PP_SIGNATURE includes POISON_POINTER_DELTA, so limit the size of the DMA
> * index to not overlap with that if set
> */
> #define PP_DMA_INDEX_BITS MIN(32, __ffs(POISON_POINTER_DELTA) - PP_DMA_INDEX_SHIFT)
> #else
> /* Use the lowest bit of PAGE_OFFSET if there's at least 8 bits available; see above */
> #define PP_DMA_INDEX_MIN_OFFSET (1 << (PP_DMA_INDEX_SHIFT + 8))
> #define PP_DMA_INDEX_BITS ((__builtin_constant_p(PAGE_OFFSET) && \
> PAGE_OFFSET >= PP_DMA_INDEX_MIN_OFFSET && \
> !(PAGE_OFFSET & (PP_DMA_INDEX_MIN_OFFSET - 1))) ? \
> MIN(32, __ffs(PAGE_OFFSET) - PP_DMA_INDEX_SHIFT) : 0)
>
> #endif
>
> #define PP_DMA_INDEX_MASK GENMASK(PP_DMA_INDEX_BITS + PP_DMA_INDEX_SHIFT - 1, \
> PP_DMA_INDEX_SHIFT)
I've managed to do an s390 cross build.
It is all quite obvious really.
For s390 PAGE_OFFSET is usually zero (I think kernel and user mappings are separate?).
This make PP_DMA_INDEX_BITS 0.
PP_SIGNATURE is 64 - so PP_DMA_INDEX_SHIFT is 7.
So it is doing GENMASK(6, 7) and, I think, expecting to get zero.
But that is taken a mistyped GENMASK(7, 6) and treated as an error.
If I rewrite __fls() and __ffs() to return 'integer constant expressions'
when the input is one I think it would always have failed.
A comment a few lines higher suggests that the code expects the mask to
be zero in this case - and handles it properly.
David
>
> I've no idea what the values are, but the 'hi' bit number must exceed that
> of 'long'.
> The __ffs() probably stop it being an 'integer constant expression'
> making it just a 'compile time constant' - which I added a test for.
>
> David
>
>
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-21 14:57 ` [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() david.laight.linux
2026-01-21 18:43 ` Vincent Mailhol
2026-01-22 1:11 ` kernel test robot
@ 2026-01-22 4:41 ` kernel test robot
2026-01-22 10:33 ` David Laight
2 siblings, 1 reply; 56+ messages in thread
From: kernel test robot @ 2026-01-22 4:41 UTC (permalink / raw)
To: david.laight.linux, Nathan Chancellor, Greg Kroah-Hartman,
Thomas Gleixner, Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers,
Arnd Bergmann, linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton
Cc: oe-kbuild-all, Linux Memory Management List, David Laight
Hi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20260120]
url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
base: next-20260120
patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com
patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
config: mips-randconfig-r132-20260122 (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/config)
compiler: mips64-linux-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601221237.soiAkwkN-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
kernel/reboot.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
lib/idr.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
include/linux/find.h:388:46: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
lib/xarray.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
lib/xarray.c: note: in included file:
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
lib/xarray.c: note: in included file (through include/linux/bitmap.h):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
lib/find_bit.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:238:46: sparse: sparse: Variable length array is used.
--
lib/bitmap-str.c: note: in included file:
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
lib/bitmap-str.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
lib/genalloc.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
mm/oom_kill.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
mm/vmscan.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
mm/shmem.c: note: in included file (through include/linux/cpumask.h, include/linux/smp.h, arch/mips/include/asm/cpu-type.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
mm/percpu.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:409:45: sparse: sparse: Variable length array is used.
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
mm/percpu.c: note: in included file:
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
mm/vmalloc.c: note: in included file (through arch/mips/include/asm/page.h, include/linux/shm.h, include/linux/sched.h, ...):
include/asm-generic/memory_model.h:30:23: sparse: sparse: unsigned value that used to be signed checked against zero?
mm/vmalloc.c:554:21: sparse: signed value source
mm/vmalloc.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
mm/vmalloc.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
mm/vmalloc.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
--
mm/slub.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
mm/hugetlb.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
mm/huge_memory.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
>> arch/mips/kernel/cmpxchg.c:20:16: sparse: sparse: Variable length array is used.
arch/mips/kernel/cmpxchg.c:61:16: sparse: sparse: Variable length array is used.
--
>> arch/mips/kernel/cpu-probe.c:709:41: sparse: sparse: Variable length array is used.
arch/mips/kernel/cpu-probe.c:712:45: sparse: sparse: Variable length array is used.
arch/mips/kernel/cpu-probe.c:214:9: sparse: sparse: cast truncates bits from constant value (3fffffffffffe000 becomes ffffe000)
arch/mips/kernel/cpu-probe.c:214:9: sparse: sparse: cast truncates bits from constant value (3fffffffffffe000 becomes ffffe000)
--
>> arch/mips/mm/tlb-r4k.c:536:20: sparse: sparse: Variable length array is used.
--
net/ethtool/ioctl.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, include/linux/smp.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
net/ethtool/bitset.c: note: in included file (through include/linux/ethtool.h, include/uapi/linux/ethtool_netlink.h, include/linux/ethtool_netlink.h):
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
net/ethtool/linkmodes.c: note: in included file (through include/linux/bitmap.h, include/linux/ethtool.h, include/uapi/linux/ethtool_netlink.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
net/ethtool/fec.c: note: in included file (through include/linux/bitmap.h, include/linux/ethtool.h, include/uapi/linux/ethtool_netlink.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
>> drivers/clk/clk-multiplier.c:48:16: sparse: sparse: Variable length array is used.
drivers/clk/clk-multiplier.c:141:17: sparse: sparse: Variable length array is used.
--
>> drivers/clk/clk-fractional-divider.c:89:17: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:90:17: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:146:25: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:147:25: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:195:25: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:196:25: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:205:17: sparse: sparse: Variable length array is used.
drivers/clk/clk-fractional-divider.c:206:17: sparse: sparse: Variable length array is used.
--
>> drivers/clocksource/mmio.c:66:27: sparse: sparse: Variable length array is used.
--
>> drivers/clocksource/timer-cadence-ttc.c:364:26: sparse: sparse: Variable length array is used.
--
>> drivers/clocksource/ingenic-timer.c:298:34: sparse: sparse: Variable length array is used.
drivers/clocksource/ingenic-timer.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
--
>> drivers/base/regmap/regmap.c:1221:26: sparse: sparse: Variable length array is used.
--
drivers/base/regmap/regcache-rbtree.c: note: in included file (through include/linux/cpumask.h, include/linux/smp.h, arch/mips/include/asm/cpu-type.h, ...):
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
drivers/base/regmap/regcache-flat.c: note: in included file:
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
>> drivers/clk/actions/owl-mux.c:42:17: sparse: sparse: Variable length array is used.
--
>> drivers/clk/actions/owl-divider.c:76:17: sparse: sparse: Variable length array is used.
--
drivers/gpio/gpiolib.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
drivers/gpio/gpiolib.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:388:46: sparse: sparse: Variable length array is used.
include/linux/find.h:188:32: sparse: sparse: Variable length array is used.
drivers/gpio/gpiolib.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
--
>> drivers/gpio/gpio-nomadik.c:285:30: sparse: sparse: Variable length array is used.
drivers/gpio/gpio-nomadik.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
kernel/sched/build_utility.c: note: in included file:
kernel/sched/debug.c:624:17: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/debug.c:624:17: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/debug.c:624:17: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/debug.c:952:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *tsk @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/debug.c:952:9: sparse: expected struct task_struct *tsk
kernel/sched/debug.c:952:9: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/debug.c:952:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct task_struct *tsk @@ got struct task_struct [noderef] __rcu *curr @@
kernel/sched/debug.c:952:9: sparse: expected struct task_struct *tsk
kernel/sched/debug.c:952:9: sparse: got struct task_struct [noderef] __rcu *curr
kernel/sched/build_utility.c: note: in included file:
kernel/sched/topology.c:115:56: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:115:56: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:115:56: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:134:60: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:134:60: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:134:60: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:157:20: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:157:20: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:157:20: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:468:19: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct perf_domain *pd @@ got struct perf_domain [noderef] __rcu *pd @@
kernel/sched/topology.c:468:19: sparse: expected struct perf_domain *pd
kernel/sched/topology.c:468:19: sparse: got struct perf_domain [noderef] __rcu *pd
kernel/sched/topology.c:638:49: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *parent @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:638:49: sparse: expected struct sched_domain *parent
kernel/sched/topology.c:638:49: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:723:50: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *parent @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:723:50: sparse: expected struct sched_domain *parent
kernel/sched/topology.c:723:50: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:731:55: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain [noderef] __rcu *[noderef] __rcu child @@ got struct sched_domain *[assigned] tmp @@
kernel/sched/topology.c:731:55: sparse: expected struct sched_domain [noderef] __rcu *[noderef] __rcu child
kernel/sched/topology.c:731:55: sparse: got struct sched_domain *[assigned] tmp
kernel/sched/topology.c:744:29: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:744:29: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/topology.c:744:29: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:749:20: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:749:20: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:749:20: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:770:13: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] tmp @@ got struct sched_domain [noderef] __rcu *sd @@
kernel/sched/topology.c:770:13: sparse: expected struct sched_domain *[assigned] tmp
kernel/sched/topology.c:770:13: sparse: got struct sched_domain [noderef] __rcu *sd
kernel/sched/topology.c:932:70: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:932:70: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:932:70: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:961:59: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:961:59: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:961:59: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1007:57: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1007:57: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:1007:57: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1009:25: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sibling @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1009:25: sparse: expected struct sched_domain *sibling
kernel/sched/topology.c:1009:25: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1017:55: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1017:55: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:1017:55: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1019:25: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *sibling @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1019:25: sparse: expected struct sched_domain *sibling
kernel/sched/topology.c:1019:25: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1089:62: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct sched_domain *sd @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1089:62: sparse: expected struct sched_domain *sd
kernel/sched/topology.c:1089:62: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1193:40: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *child @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:1193:40: sparse: expected struct sched_domain *child
kernel/sched/topology.c:1193:40: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1331:9: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:1331:9: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:1331:9: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:1680:43: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain [noderef] __rcu *child @@ got struct sched_domain *child @@
kernel/sched/topology.c:1680:43: sparse: expected struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:1680:43: sparse: got struct sched_domain *child
kernel/sched/topology.c:2470:31: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain [noderef] __rcu *parent @@ got struct sched_domain *sd @@
kernel/sched/topology.c:2470:31: sparse: expected struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:2470:31: sparse: got struct sched_domain *sd
kernel/sched/topology.c:2591:57: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:2591:57: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:2591:57: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:2612:56: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected struct sched_domain *child @@ got struct sched_domain [noderef] __rcu *child @@
kernel/sched/topology.c:2612:56: sparse: expected struct sched_domain *child
kernel/sched/topology.c:2612:56: sparse: got struct sched_domain [noderef] __rcu *child
kernel/sched/topology.c:2611:57: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:2611:57: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:2611:57: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/topology.c:2666:57: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct sched_domain *[assigned] sd @@ got struct sched_domain [noderef] __rcu *parent @@
kernel/sched/topology.c:2666:57: sparse: expected struct sched_domain *[assigned] sd
kernel/sched/topology.c:2666:57: sparse: got struct sched_domain [noderef] __rcu *parent
kernel/sched/build_utility.c: note: in included file:
kernel/sched/build_utility.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, include/linux/smp.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
kernel/sched/build_utility.c: note: in included file:
kernel/sched/sched.h:2360:25: sparse: sparse: incompatible types in comparison expression (different address spaces):
kernel/sched/sched.h:2360:25: sparse: struct task_struct [noderef] __rcu *
kernel/sched/sched.h:2360:25: sparse: struct task_struct *
--
>> drivers/clk/ingenic/cgu.c:95:42: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:97:42: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:102:27: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:224:18: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:227:18: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:231:26: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:345:26: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:389:24: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:423:31: sparse: sparse: Variable length array is used.
drivers/clk/ingenic/cgu.c:553:24: sparse: sparse: Variable length array is used.
--
kernel/irq/chip.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
kernel/irq/irq_sim.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
drivers/input/rmi4/rmi_driver.c: note: in included file (through include/linux/bitmap.h):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
drivers/input/rmi4/rmi_driver.c: note: in included file:
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
drivers/input/rmi4/rmi_driver.c: note: in included file (through include/linux/bitmap.h):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
--
>> drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c:338:31: sparse: sparse: Variable length array is used.
--
>> drivers/mfd/atmel-smc.c:56:32: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:57:32: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:120:27: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:159:25: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:198:25: sparse: sparse: Variable length array is used.
drivers/mfd/atmel-smc.c:236:25: sparse: sparse: Variable length array is used.
--
>> kernel/time/sched_clock.c:194:20: sparse: sparse: Variable length array is used.
--
>> drivers/mtd/nand/bbt.c:87:25: sparse: sparse: Variable length array is used.
drivers/mtd/nand/bbt.c:111:38: sparse: sparse: Variable length array is used.
drivers/mtd/nand/bbt.c:116:20: sparse: sparse: Variable length array is used.
drivers/mtd/nand/bbt.c:122:28: sparse: sparse: Variable length array is used.
--
drivers/opp/cpu.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
drivers/pci/pci.c:1157:36: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted pci_power_t [usertype] current_state @@ got int @@
drivers/pci/pci.c:1157:36: sparse: expected restricted pci_power_t [usertype] current_state
drivers/pci/pci.c:1157:36: sparse: got int
drivers/pci/pci.c:1336:15: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted pci_power_t [assigned] [usertype] state @@ got int @@
drivers/pci/pci.c:1336:15: sparse: expected restricted pci_power_t [assigned] [usertype] state
drivers/pci/pci.c:1336:15: sparse: got int
drivers/pci/pci.c:1338:50: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1338:69: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1391:28: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted pci_power_t [usertype] current_state @@ got int @@
drivers/pci/pci.c:1391:28: sparse: expected restricted pci_power_t [usertype] current_state
drivers/pci/pci.c:1391:28: sparse: got int
drivers/pci/pci.c:1481:16: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1481:35: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1481:52: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1481:70: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1506:15: sparse: sparse: invalid assignment: |=
drivers/pci/pci.c:1506:15: sparse: left side has type unsigned short
drivers/pci/pci.c:1506:15: sparse: right side has type restricted pci_power_t
drivers/pci/pci.c:1518:28: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted pci_power_t [usertype] current_state @@ got int @@
drivers/pci/pci.c:1518:28: sparse: expected restricted pci_power_t [usertype] current_state
drivers/pci/pci.c:1518:28: sparse: got int
drivers/pci/pci.c:1535:13: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1535:21: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1537:18: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1537:26: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1560:13: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1560:22: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:1865:38: sparse: sparse: array of flexible structures
drivers/pci/pci.c:2343:44: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2662:60: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2663:30: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2834:20: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2834:38: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2857:49: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:2857:67: sparse: sparse: restricted pci_power_t degrades to integer
drivers/pci/pci.c:4486:13: sparse: sparse: invalid assignment: |=
drivers/pci/pci.c:4486:13: sparse: left side has type unsigned short
drivers/pci/pci.c:4486:13: sparse: right side has type restricted pci_power_t
drivers/pci/pci.c:4491:13: sparse: sparse: invalid assignment: |=
drivers/pci/pci.c:4491:13: sparse: left side has type unsigned short
drivers/pci/pci.c:4491:13: sparse: right side has type restricted pci_power_t
>> drivers/pci/pci.c:5983:19: sparse: sparse: Variable length array is used.
drivers/pci/pci.c:1112:24: sparse: sparse: incorrect type in return expression (different base types) @@ expected int @@ got restricted pci_power_t [usertype] @@
drivers/pci/pci.c:1112:24: sparse: expected int
drivers/pci/pci.c:1112:24: sparse: got restricted pci_power_t [usertype]
drivers/pci/pci.c:1112:24: sparse: sparse: incorrect type in return expression (different base types) @@ expected int @@ got restricted pci_power_t [usertype] @@
drivers/pci/pci.c:1112:24: sparse: expected int
drivers/pci/pci.c:1112:24: sparse: got restricted pci_power_t [usertype]
drivers/pci/pci.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
--
drivers/perf/xgene_pmu.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:388:46: sparse: sparse: Variable length array is used.
>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
--
>> drivers/clk/renesas/rcar-gen3-cpg.c:287:22: sparse: sparse: Variable length array is used.
--
>> drivers/clk/renesas/rcar-gen4-cpg.c:400:22: sparse: sparse: Variable length array is used.
--
drivers/mtd/nand/raw/nand_macronix.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
>> drivers/clk/spacemit/ccu_mix.c:168:16: sparse: sparse: Variable length array is used.
drivers/clk/spacemit/ccu_mix.c:193:16: sparse: sparse: Variable length array is used.
--
>> drivers/clk/sprd/mux.c:56:17: sparse: sparse: Variable length array is used.
--
>> drivers/clk/sprd/div.c:60:17: sparse: sparse: Variable length array is used.
--
>> drivers/clk/sprd/pll.c:77:24: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:116:13: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:120:34: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:121:31: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:124:14: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:125:32: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:127:24: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:128:21: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:129:32: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:131:24: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:164:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:170:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:181:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:186:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:192:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:198:16: sparse: sparse: Variable length array is used.
drivers/clk/sprd/pll.c:210:16: sparse: sparse: Variable length array is used.
--
>> drivers/pci/pcie/bwctrl.c:94:26: sparse: sparse: Variable length array is used.
--
>> drivers/pinctrl/renesas/core.c:884:26: sparse: sparse: Variable length array is used.
drivers/pinctrl/renesas/core.c:942:34: sparse: sparse: Variable length array is used.
drivers/pinctrl/renesas/core.c:1241:34: sparse: sparse: Variable length array is used.
--
>> drivers/pinctrl/renesas/pinctrl.c:492:51: sparse: sparse: Variable length array is used.
drivers/pinctrl/renesas/pinctrl.c:527:17: sparse: sparse: Variable length array is used.
--
drivers/pci/controller/pcie-xilinx-dma-pl.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
drivers/pci/controller/pcie-xilinx-dma-pl.c: note: in included file (through include/linux/cpumask.h, arch/mips/include/asm/processor.h, arch/mips/include/asm/thread_info.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
--
drivers/pci/controller/dwc/pcie-designware-host.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, include/linux/smp.h, ...):
include/linux/find.h:69:31: sparse: sparse: Variable length array is used.
drivers/pci/controller/dwc/pcie-designware-host.c: note: in included file (through include/linux/cpumask.h, include/linux/smp.h, arch/mips/include/asm/cpu-type.h, ...):
include/linux/bitmap.h:488:25: sparse: sparse: Variable length array is used.
>> include/linux/bitmap.h:504:26: sparse: sparse: Variable length array is used.
vim +209 include/linux/find.h
c56f97c5c71f17 include/linux/find.h Yury Norov [NVIDIA] 2025-06-19 48
19de85ef574c3a include/asm-generic/bitops/find.h Akinobu Mita 2011-05-26 49 #ifndef find_next_bit
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 50 /**
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 51 * find_next_bit - find the next set bit in a memory region
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 52 * @addr: The address to base the search on
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 53 * @size: The bitmap size in bits
6d7131bd52b3e0 include/linux/find.h Anna-Maria Behnsen 2022-04-11 54 * @offset: The bitnumber to start searching at
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 55 *
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 56 * Returns the bit number for the next set bit
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 57 * If no bits are set, returns @size.
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 58 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 59 static __always_inline
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 60 unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 61 unsigned long offset)
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 62 {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 63 if (small_const_nbits(size)) {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 64 unsigned long val;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 65
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 66 if (unlikely(offset >= size))
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 67 return size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 68
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 @69 val = *addr & GENMASK(size - 1, offset);
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 70 return val ? __ffs(val) : size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 71 }
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 72
e79864f3164c57 include/linux/find.h Yury Norov 2022-09-14 73 return _find_next_bit(addr, size, offset);
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 74 }
19de85ef574c3a include/asm-generic/bitops/find.h Akinobu Mita 2011-05-26 75 #endif
c7f612cdf091de include/asm-generic/bitops/find.h Akinobu Mita 2006-03-26 76
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 77 #ifndef find_next_and_bit
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 78 /**
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 79 * find_next_and_bit - find the next set bit in both memory regions
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 80 * @addr1: The first address to base the search on
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 81 * @addr2: The second address to base the search on
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 82 * @size: The bitmap size in bits
6d7131bd52b3e0 include/linux/find.h Anna-Maria Behnsen 2022-04-11 83 * @offset: The bitnumber to start searching at
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 84 *
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 85 * Returns the bit number for the next set bit
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 86 * If no bits are set, returns @size.
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 87 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 88 static __always_inline
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 89 unsigned long find_next_and_bit(const unsigned long *addr1,
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 90 const unsigned long *addr2, unsigned long size,
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 91 unsigned long offset)
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 92 {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 93 if (small_const_nbits(size)) {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 94 unsigned long val;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 95
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 96 if (unlikely(offset >= size))
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 97 return size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 98
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 99 val = *addr1 & *addr2 & GENMASK(size - 1, offset);
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 100 return val ? __ffs(val) : size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 101 }
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 102
e79864f3164c57 include/linux/find.h Yury Norov 2022-09-14 103 return _find_next_and_bit(addr1, addr2, size, offset);
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 104 }
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 105 #endif
0ade34c37012ea include/asm-generic/bitops/find.h Clement Courbet 2018-02-06 106
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 107 #ifndef find_next_andnot_bit
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 108 /**
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 109 * find_next_andnot_bit - find the next set bit in *addr1 excluding all the bits
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 110 * in *addr2
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 111 * @addr1: The first address to base the search on
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 112 * @addr2: The second address to base the search on
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 113 * @size: The bitmap size in bits
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 114 * @offset: The bitnumber to start searching at
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 115 *
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 116 * Returns the bit number for the next set bit
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 117 * If no bits are set, returns @size.
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 118 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 119 static __always_inline
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 120 unsigned long find_next_andnot_bit(const unsigned long *addr1,
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 121 const unsigned long *addr2, unsigned long size,
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 122 unsigned long offset)
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 123 {
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 124 if (small_const_nbits(size)) {
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 125 unsigned long val;
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 126
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 127 if (unlikely(offset >= size))
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 128 return size;
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 129
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 130 val = *addr1 & ~*addr2 & GENMASK(size - 1, offset);
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 131 return val ? __ffs(val) : size;
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 132 }
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 133
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 134 return _find_next_andnot_bit(addr1, addr2, size, offset);
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 135 }
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 136 #endif
90d482908eedd5 include/linux/find.h Valentin Schneider 2022-10-03 137
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 138 #ifndef find_next_or_bit
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 139 /**
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 140 * find_next_or_bit - find the next set bit in either memory regions
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 141 * @addr1: The first address to base the search on
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 142 * @addr2: The second address to base the search on
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 143 * @size: The bitmap size in bits
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 144 * @offset: The bitnumber to start searching at
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 145 *
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 146 * Returns the bit number for the next set bit
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 147 * If no bits are set, returns @size.
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 148 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 149 static __always_inline
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 150 unsigned long find_next_or_bit(const unsigned long *addr1,
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 151 const unsigned long *addr2, unsigned long size,
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 152 unsigned long offset)
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 153 {
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 154 if (small_const_nbits(size)) {
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 155 unsigned long val;
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 156
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 157 if (unlikely(offset >= size))
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 158 return size;
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 159
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 160 val = (*addr1 | *addr2) & GENMASK(size - 1, offset);
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 161 return val ? __ffs(val) : size;
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 162 }
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 163
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 164 return _find_next_or_bit(addr1, addr2, size, offset);
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 165 }
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 166 #endif
1470afefc3c42d include/linux/find.h Dave Chinner 2023-03-15 167
19de85ef574c3a include/asm-generic/bitops/find.h Akinobu Mita 2011-05-26 168 #ifndef find_next_zero_bit
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 169 /**
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 170 * find_next_zero_bit - find the next cleared bit in a memory region
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 171 * @addr: The address to base the search on
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 172 * @size: The bitmap size in bits
6d7131bd52b3e0 include/linux/find.h Anna-Maria Behnsen 2022-04-11 173 * @offset: The bitnumber to start searching at
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 174 *
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 175 * Returns the bit number of the next zero bit
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 176 * If no bits are zero, returns @size.
d852a6afd91fc9 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 177 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 178 static __always_inline
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 179 unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 180 unsigned long offset)
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 181 {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 182 if (small_const_nbits(size)) {
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 183 unsigned long val;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 184
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 185 if (unlikely(offset >= size))
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 186 return size;
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 187
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 188 val = *addr | ~GENMASK(size - 1, offset);
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 189 return val == ~0UL ? size : ffz(val);
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 190 }
277a20a498d307 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 191
e79864f3164c57 include/linux/find.h Yury Norov 2022-09-14 192 return _find_next_zero_bit(addr, size, offset);
5c88af59f9abc2 include/asm-generic/bitops/find.h Yury Norov 2021-05-06 193 }
19de85ef574c3a include/asm-generic/bitops/find.h Akinobu Mita 2011-05-26 194 #endif
c7f612cdf091de include/asm-generic/bitops/find.h Akinobu Mita 2006-03-26 195
b7ec62d7ee0f0b include/asm-generic/bitops/find.h Yury Norov 2021-08-14 196 #ifndef find_first_bit
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 197 /**
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 198 * find_first_bit - find the first set bit in a memory region
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 199 * @addr: The address to start the search at
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 200 * @size: The maximum number of bits to search
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 201 *
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 202 * Returns the bit number of the first set bit.
ec778edf97dcaa include/asm-generic/bitops/find.h Cody P Schafer 2013-11-12 203 * If no bits are set, returns @size.
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 204 */
fda1dd3c54ef3c include/linux/find.h Yury Norov 2024-07-18 205 static __always_inline
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 206 unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 207 {
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 208 if (small_const_nbits(size)) {
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 @209 unsigned long val = *addr & GENMASK(size - 1, 0);
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 210
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 211 return val ? __ffs(val) : size;
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 212 }
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 213
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 214 return _find_first_bit(addr, size);
2cc7b6a44ac21d include/asm-generic/bitops/find.h Yury Norov 2021-05-06 215 }
b7ec62d7ee0f0b include/asm-generic/bitops/find.h Yury Norov 2021-08-14 216 #endif
708ff2a0097b02 include/asm-generic/bitops/find.h Akinobu Mita 2010-09-29 217
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-22 4:41 ` kernel test robot
@ 2026-01-22 10:33 ` David Laight
2026-01-22 14:26 ` Andy Shevchenko
2026-01-23 1:24 ` Philip Li
0 siblings, 2 replies; 56+ messages in thread
From: David Laight @ 2026-01-22 10:33 UTC (permalink / raw)
To: kernel test robot
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton,
oe-kbuild-all, Linux Memory Management List
On Thu, 22 Jan 2026 12:41:22 +0800
kernel test robot <lkp@intel.com> wrote:
> Hi,
>
> kernel test robot noticed the following build warnings:
>
> [auto build test WARNING on next-20260120]
>
> url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
> base: next-20260120
> patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com
> patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
> config: mips-randconfig-r132-20260122 (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/config)
> compiler: mips64-linux-gcc (GCC) 10.5.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202601221237.soiAkwkN-lkp@intel.com/
>
> sparse warnings: (new ones prefixed by >>)
> kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
> >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
Can we stop sparse complaining about sizeof(VLA) ?
David
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-22 10:33 ` David Laight
@ 2026-01-22 14:26 ` Andy Shevchenko
2026-01-22 14:55 ` David Laight
2026-01-23 1:25 ` Philip Li
2026-01-23 1:24 ` Philip Li
1 sibling, 2 replies; 56+ messages in thread
From: Andy Shevchenko @ 2026-01-22 14:26 UTC (permalink / raw)
To: David Laight
Cc: kernel test robot, Nathan Chancellor, Greg Kroah-Hartman,
Thomas Gleixner, Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers,
Arnd Bergmann, linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Kees Cook, Andrew Morton, oe-kbuild-all,
Linux Memory Management List
On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote:
> On Thu, 22 Jan 2026 12:41:22 +0800
> kernel test robot <lkp@intel.com> wrote:
> > sparse warnings: (new ones prefixed by >>)
> > kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
> > >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
>
> Can we stop sparse complaining about sizeof(VLA) ?
First of all, the LKP should install the fork of sparse by Al Viro. That will
fix tons of warnings that are related to modules and speed up the process
itself.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-22 14:26 ` Andy Shevchenko
@ 2026-01-22 14:55 ` David Laight
2026-01-23 1:25 ` Philip Li
1 sibling, 0 replies; 56+ messages in thread
From: David Laight @ 2026-01-22 14:55 UTC (permalink / raw)
To: Andy Shevchenko
Cc: kernel test robot, Nathan Chancellor, Greg Kroah-Hartman,
Thomas Gleixner, Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers,
Arnd Bergmann, linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Kees Cook, Andrew Morton, oe-kbuild-all,
Linux Memory Management List
On Thu, 22 Jan 2026 16:26:44 +0200
Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote:
> > On Thu, 22 Jan 2026 12:41:22 +0800
> > kernel test robot <lkp@intel.com> wrote:
>
> > > sparse warnings: (new ones prefixed by >>)
> > > kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
> > > >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
> >
> > Can we stop sparse complaining about sizeof(VLA) ?
>
> First of all, the LKP should install the fork of sparse by Al Viro. That will
> fix tons of warnings that are related to modules and speed up the process
> itself.
>
The problem I have is I want to generate a compile time error inside:
__builtin_choose_expr(__is_constexpr(x), x && error_a(),
statically_true(y) && error_b());
Neither static_assert() nor a negative bitfield can be used in error_a()
because they are errors when x isn't isn't a 'constexpr',
There is less of a problem for error_b() it can contain a function call,
but can't contain {( ...)}.
One of the compiler complained about sizeof (char [-!!(expr)]) as well.
I'm not sure of anything else that can be use to get an error.
I could use 0 >> -1 but that is only a warning, at least the error message
is related to the bug.
Any other ideas?
David
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-22 14:26 ` Andy Shevchenko
2026-01-22 14:55 ` David Laight
@ 2026-01-23 1:25 ` Philip Li
2026-01-23 8:01 ` Vincent Mailhol
1 sibling, 1 reply; 56+ messages in thread
From: Philip Li @ 2026-01-23 1:25 UTC (permalink / raw)
To: Andy Shevchenko
Cc: David Laight, kernel test robot, Nathan Chancellor,
Greg Kroah-Hartman, Thomas Gleixner, Peter Zijlstra, Ingo Molnar,
Mathieu Desnoyers, Arnd Bergmann, linux-arch, linux-kernel,
Yury Norov, Jani Nikula, Vincent Mailhol, Kees Cook,
Andrew Morton, oe-kbuild-all, Linux Memory Management List
On Thu, Jan 22, 2026 at 04:26:44PM +0200, Andy Shevchenko wrote:
> On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote:
> > On Thu, 22 Jan 2026 12:41:22 +0800
> > kernel test robot <lkp@intel.com> wrote:
>
> > > sparse warnings: (new ones prefixed by >>)
> > > kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
> > > >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
> >
> > Can we stop sparse complaining about sizeof(VLA) ?
>
> First of all, the LKP should install the fork of sparse by Al Viro. That will
> fix tons of warnings that are related to modules and speed up the process
> itself.
Thanks Andy, i will switch to the repo from Al Viro for sparse.
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-23 1:25 ` Philip Li
@ 2026-01-23 8:01 ` Vincent Mailhol
2026-01-23 8:11 ` Andy Shevchenko
0 siblings, 1 reply; 56+ messages in thread
From: Vincent Mailhol @ 2026-01-23 8:01 UTC (permalink / raw)
To: Philip Li, Andy Shevchenko, Chris Li, Al Viro
Cc: David Laight, kernel test robot, Nathan Chancellor,
Greg Kroah-Hartman, Thomas Gleixner, Peter Zijlstra, Ingo Molnar,
Mathieu Desnoyers, Arnd Bergmann, linux-arch, linux-kernel,
Yury Norov, Jani Nikula, Kees Cook, Andrew Morton, oe-kbuild-all,
Linux Memory Management List
Adding the relevant parties to the discussion:
+To: Al Viro
+To: Chris Li
On 23/01/2026 at 02:25, Philip Li wrote:
> On Thu, Jan 22, 2026 at 04:26:44PM +0200, Andy Shevchenko wrote:
>> On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote:
>>> On Thu, 22 Jan 2026 12:41:22 +0800
>>> kernel test robot <lkp@intel.com> wrote:
>>
>>>> sparse warnings: (new ones prefixed by >>)
>>>> kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
>>>>>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
>>>
>>> Can we stop sparse complaining about sizeof(VLA) ?
>>
>> First of all, the LKP should install the fork of sparse by Al Viro. That will
>> fix tons of warnings that are related to modules and speed up the process
>> itself.
>
> Thanks Andy, i will switch to the repo from Al Viro for sparse.
Al Viro's fork just adds 8 commit on top of the upstream sparse repo.
Wouldn't it be possible to just merge those?
That would be much less confusing.
Yours sincerely,
Vincent Mailhol
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-23 8:01 ` Vincent Mailhol
@ 2026-01-23 8:11 ` Andy Shevchenko
2026-01-23 8:20 ` Al Viro
0 siblings, 1 reply; 56+ messages in thread
From: Andy Shevchenko @ 2026-01-23 8:11 UTC (permalink / raw)
To: Vincent Mailhol
Cc: Philip Li, Chris Li, Al Viro, David Laight, kernel test robot,
Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Jani Nikula, Kees Cook,
Andrew Morton, oe-kbuild-all, Linux Memory Management List
On Fri, Jan 23, 2026 at 09:01:04AM +0100, Vincent Mailhol wrote:
> Adding the relevant parties to the discussion:
>
> +To: Al Viro
> +To: Chris Li
>
> On 23/01/2026 at 02:25, Philip Li wrote:
> > On Thu, Jan 22, 2026 at 04:26:44PM +0200, Andy Shevchenko wrote:
> >> On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote:
> >>> On Thu, 22 Jan 2026 12:41:22 +0800
> >>> kernel test robot <lkp@intel.com> wrote:
> >>
> >>>> sparse warnings: (new ones prefixed by >>)
> >>>> kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
> >>>>>> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
> >>>
> >>> Can we stop sparse complaining about sizeof(VLA) ?
> >>
> >> First of all, the LKP should install the fork of sparse by Al Viro. That will
> >> fix tons of warnings that are related to modules and speed up the process
> >> itself.
> >
> > Thanks Andy, i will switch to the repo from Al Viro for sparse.
>
> Al Viro's fork just adds 8 commit on top of the upstream sparse repo.
> Wouldn't it be possible to just merge those?
Ideally yes, but you also should kick the distro's asses to update it, and
the sparse should bump its version...
> That would be much less confusing.
Seems Al become a sparse maintainer de facto :-)
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-23 8:11 ` Andy Shevchenko
@ 2026-01-23 8:20 ` Al Viro
2026-01-23 8:24 ` Andy Shevchenko
0 siblings, 1 reply; 56+ messages in thread
From: Al Viro @ 2026-01-23 8:20 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Vincent Mailhol, Philip Li, Chris Li, David Laight,
kernel test robot, Nathan Chancellor, Greg Kroah-Hartman,
Thomas Gleixner, Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers,
Arnd Bergmann, linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Kees Cook, Andrew Morton, oe-kbuild-all,
Linux Memory Management List
On Fri, Jan 23, 2026 at 10:11:19AM +0200, Andy Shevchenko wrote:
> > Al Viro's fork just adds 8 commit on top of the upstream sparse repo.
> > Wouldn't it be possible to just merge those?
>
> Ideally yes, but you also should kick the distro's asses to update it, and
> the sparse should bump its version...
>
> > That would be much less confusing.
>
> Seems Al become a sparse maintainer de facto :-)
Huh? What happened to Chris? FWIW, I do have some followups to that series
sitting locally; need to get that finished (mostly for proper __VA_OPT__
handling; that got stalled on the lovely corner cases where the interplay
with side effects of macro expansion is really nasty - gcc and clang do
not agree and gcc is arguably buggy) and posted.
I've done quite a bit of sparse work over the years, but I would rather
prefer somebody else as overall maintainer, TYVM...
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-23 8:20 ` Al Viro
@ 2026-01-23 8:24 ` Andy Shevchenko
2026-01-23 8:32 ` Vincent Mailhol
0 siblings, 1 reply; 56+ messages in thread
From: Andy Shevchenko @ 2026-01-23 8:24 UTC (permalink / raw)
To: Al Viro
Cc: Vincent Mailhol, Philip Li, Chris Li, David Laight,
kernel test robot, Nathan Chancellor, Greg Kroah-Hartman,
Thomas Gleixner, Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers,
Arnd Bergmann, linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Kees Cook, Andrew Morton, oe-kbuild-all,
Linux Memory Management List
On Fri, Jan 23, 2026 at 08:20:27AM +0000, Al Viro wrote:
> On Fri, Jan 23, 2026 at 10:11:19AM +0200, Andy Shevchenko wrote:
>
> > > Al Viro's fork just adds 8 commit on top of the upstream sparse repo.
> > > Wouldn't it be possible to just merge those?
> >
> > Ideally yes, but you also should kick the distro's asses to update it, and
> > the sparse should bump its version...
> >
> > > That would be much less confusing.
> >
> > Seems Al become a sparse maintainer de facto :-)
>
> Huh? What happened to Chris?
I don't know, but upstream sparse haven't applied any solution for
MODULE*("FOO") stuff, nor reaction on my ping in that discussion
(I did it like week or so ago).
> FWIW, I do have some followups to that series
> sitting locally; need to get that finished (mostly for proper __VA_OPT__
> handling; that got stalled on the lovely corner cases where the interplay
> with side effects of macro expansion is really nasty - gcc and clang do
> not agree and gcc is arguably buggy) and posted.
Thanks for doing all this!
> I've done quite a bit of sparse work over the years, but I would rather
> prefer somebody else as overall maintainer, TYVM...
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-23 8:24 ` Andy Shevchenko
@ 2026-01-23 8:32 ` Vincent Mailhol
2026-01-23 8:46 ` Andy Shevchenko
0 siblings, 1 reply; 56+ messages in thread
From: Vincent Mailhol @ 2026-01-23 8:32 UTC (permalink / raw)
To: Andy Shevchenko, Al Viro, Chris Li
Cc: Vincent Mailhol, Philip Li, David Laight, kernel test robot,
Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Jani Nikula, Kees Cook,
Andrew Morton, oe-kbuild-all, Linux Memory Management List
On 23/01/2026 at 09:24, Andy Shevchenko wrote:
> On Fri, Jan 23, 2026 at 08:20:27AM +0000, Al Viro wrote:
>> On Fri, Jan 23, 2026 at 10:11:19AM +0200, Andy Shevchenko wrote:
>>
>>>> Al Viro's fork just adds 8 commit on top of the upstream sparse repo.
>>>> Wouldn't it be possible to just merge those?
>>>
>>> Ideally yes, but you also should kick the distro's asses to update it, and
>>> the sparse should bump its version...
>>>
>>>> That would be much less confusing.
>>>
>>> Seems Al become a sparse maintainer de facto :-)
>>
>> Huh? What happened to Chris?
After the project hiatus, I can imagine that there is some confusion :)
But Chris is back in his role of maintainer since September 2025. See:
- https://lore.kernel.org/linux-sparse/CACePvbXDO1ZybDu3RaFhED9D-9gC6LTMpWrxoh5xD+ZO5SLdzA@mail.gmail.com/
- https://git.kernel.org/pub/scm/devel/sparse/sparse.git/commit/?id=67f0a03cee4637e495151c48a02be642a158cbbb
> I don't know, but upstream sparse haven't applied any solution for
> MODULE*("FOO") stuff, nor reaction on my ping in that discussion
> (I did it like week or so ago).
I am out of context here, but were the correct people CCed?
Yours sincerely,
Vincent Mailhol
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-23 8:32 ` Vincent Mailhol
@ 2026-01-23 8:46 ` Andy Shevchenko
0 siblings, 0 replies; 56+ messages in thread
From: Andy Shevchenko @ 2026-01-23 8:46 UTC (permalink / raw)
To: Vincent Mailhol
Cc: Al Viro, Chris Li, Philip Li, David Laight, kernel test robot,
Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Jani Nikula, Kees Cook,
Andrew Morton, oe-kbuild-all, Linux Memory Management List
On Fri, Jan 23, 2026 at 09:32:39AM +0100, Vincent Mailhol wrote:
> On 23/01/2026 at 09:24, Andy Shevchenko wrote:
> > On Fri, Jan 23, 2026 at 08:20:27AM +0000, Al Viro wrote:
> >> On Fri, Jan 23, 2026 at 10:11:19AM +0200, Andy Shevchenko wrote:
...
> >>>> Al Viro's fork just adds 8 commit on top of the upstream sparse repo.
> >>>> Wouldn't it be possible to just merge those?
> >>>
> >>> Ideally yes, but you also should kick the distro's asses to update it, and
> >>> the sparse should bump its version...
> >>>
> >>>> That would be much less confusing.
> >>>
> >>> Seems Al become a sparse maintainer de facto :-)
> >>
> >> Huh? What happened to Chris?
>
> After the project hiatus, I can imagine that there is some confusion :)
>
> But Chris is back in his role of maintainer since September 2025. See:
>
> - https://lore.kernel.org/linux-sparse/CACePvbXDO1ZybDu3RaFhED9D-9gC6LTMpWrxoh5xD+ZO5SLdzA@mail.gmail.com/
> - https://git.kernel.org/pub/scm/devel/sparse/sparse.git/commit/?id=67f0a03cee4637e495151c48a02be642a158cbbb
>
> > I don't know, but upstream sparse haven't applied any solution for
> > MODULE*("FOO") stuff, nor reaction on my ping in that discussion
> > (I did it like week or so ago).
My ping: https://lore.kernel.org/all/aV9vo7_turBr84bs@black.igk.intel.com/
But now I realised that there was another version of the series, and Chris
seems active there.
https://lore.kernel.org/all/CACePvbU5Pqo=bw_j8arOq16o1JBOSwPtuMZBVozy4FV7YsSLGw@mail.gmail.com/
> I am out of context here, but were the correct people CCed?
I dunno.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
2026-01-22 10:33 ` David Laight
2026-01-22 14:26 ` Andy Shevchenko
@ 2026-01-23 1:24 ` Philip Li
1 sibling, 0 replies; 56+ messages in thread
From: Philip Li @ 2026-01-23 1:24 UTC (permalink / raw)
To: David Laight
Cc: kernel test robot, Nathan Chancellor, Greg Kroah-Hartman,
Thomas Gleixner, Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers,
Arnd Bergmann, linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton,
oe-kbuild-all, Linux Memory Management List
On Thu, Jan 22, 2026 at 10:33:37AM +0000, David Laight wrote:
> On Thu, 22 Jan 2026 12:41:22 +0800
> kernel test robot <lkp@intel.com> wrote:
>
> > Hi,
> >
> > kernel test robot noticed the following build warnings:
> >
> > [auto build test WARNING on next-20260120]
> >
> > url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
> > base: next-20260120
> > patch link: https://lore.kernel.org/r/20260121145731.3623-12-david.laight.linux%40gmail.com
> > patch subject: [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT()
> > config: mips-randconfig-r132-20260122 (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/config)
> > compiler: mips64-linux-gcc (GCC) 10.5.0
> > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601221237.soiAkwkN-lkp@intel.com/reproduce)
> >
> > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > the same patch/commit), kindly add following tags
> > | Reported-by: kernel test robot <lkp@intel.com>
> > | Closes: https://lore.kernel.org/oe-kbuild-all/202601221237.soiAkwkN-lkp@intel.com/
> >
> > sparse warnings: (new ones prefixed by >>)
> > kernel/kthread.c: note: in included file (through include/linux/bitmap.h, include/linux/cpumask.h, arch/mips/include/asm/processor.h, ...):
> > >> include/linux/find.h:209:45: sparse: sparse: Variable length array is used.
>
> Can we stop sparse complaining about sizeof(VLA) ?
Got it, we will avoid the direct report this 'sparse: Variable length array is used' warning.
>
> David
>
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (10 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 11/14] bit: Strengthen compile-time tests in GENMASK() and BIT() david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-01-21 15:17 ` Thomas Weißschuh
` (3 more replies)
2026-01-21 14:57 ` [PATCH next 13/14] test_bits: Change all the tests to be compile-time tests david.laight.linux
2026-01-21 14:57 ` [PATCH next 14/14] test_bits: include some invalid input tests for GENMASK_INPUT_CHECK() david.laight.linux
13 siblings, 4 replies; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
The definition of BIT() was moved from linux/bits.h to vdso/bits.h to
isolate the vdso from 'normal' kernel headers.
BIT_ULL() was then moved to be defined in the same place for consistency.
Since then linux/bits.h had gained BIT_Unn() and it really makes sense
for BIT() and BIT_ULL() to be defined in the same place.
Move BIT_ULL() and make code that include both headers use the definition
of BIT() from linux/bits.h
Add BIT_U128() for completness.
This lets BIT() pick up the extra compile time checks for W=[1c] builds
that detect errors like:
long foo(void) { int x = 64; return BIT(x); }
For which clang (silently) just generates a 'return' instruction.
Note that nothing the the x86-64 build relies on the definition in
vdso/bits.h, linux/bits.h is always included.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
include/linux/bits.h | 7 ++++++-
include/vdso/bits.h | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/linux/bits.h b/include/linux/bits.h
index 0f559038981d..3dd32b9eef35 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -2,7 +2,6 @@
#ifndef __LINUX_BITS_H
#define __LINUX_BITS_H
-#include <vdso/bits.h>
#include <uapi/linux/bits.h>
#define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
@@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
#endif /* defined(__ASSEMBLY__) */
+/* Prefer this definition of BIT() to the one in vdso/bits.h */
+#undef BIT
+#define __VDSO_BITS_H
+#define BIT(nr) BIT_TYPE(unsigned long, nr)
+#define BIT_ULL(nr) BIT_TYPE(unsigned long long, nr)
#define BIT_U8(nr) BIT_TYPE(u8, nr)
#define BIT_U16(nr) BIT_TYPE(u16, nr)
#define BIT_U32(nr) BIT_TYPE(u32, nr)
#define BIT_U64(nr) BIT_TYPE(u64, nr)
+#define BIT_U128(nr) BIT_TYPE(u128, nr)
#if defined(__ASSEMBLY__)
diff --git a/include/vdso/bits.h b/include/vdso/bits.h
index 388b212088ea..a6ac1e6b637c 100644
--- a/include/vdso/bits.h
+++ b/include/vdso/bits.h
@@ -4,7 +4,7 @@
#include <vdso/const.h>
+/* Most code picks up BIT() from linux/bits.h */
#define BIT(nr) (UL(1) << (nr))
-#define BIT_ULL(nr) (ULL(1) << (nr))
#endif /* __VDSO_BITS_H */
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
2026-01-21 14:57 ` [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h david.laight.linux
@ 2026-01-21 15:17 ` Thomas Weißschuh
2026-01-21 19:24 ` David Laight
2026-01-22 0:50 ` kernel test robot
` (2 subsequent siblings)
3 siblings, 1 reply; 56+ messages in thread
From: Thomas Weißschuh @ 2026-01-21 15:17 UTC (permalink / raw)
To: david.laight.linux
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Wed, Jan 21, 2026 at 02:57:29PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> The definition of BIT() was moved from linux/bits.h to vdso/bits.h to
> isolate the vdso from 'normal' kernel headers.
> BIT_ULL() was then moved to be defined in the same place for consistency.
>
> Since then linux/bits.h had gained BIT_Unn() and it really makes sense
> for BIT() and BIT_ULL() to be defined in the same place.
>
> Move BIT_ULL() and make code that include both headers use the definition
> of BIT() from linux/bits.h
> Add BIT_U128() for completness.
>
> This lets BIT() pick up the extra compile time checks for W=[1c] builds
> that detect errors like:
> long foo(void) { int x = 64; return BIT(x); }
> For which clang (silently) just generates a 'return' instruction.
>
> Note that nothing the the x86-64 build relies on the definition in
> vdso/bits.h, linux/bits.h is always included.
>
> Signed-off-by: David Laight <david.laight.linux@gmail.com>
> ---
> include/linux/bits.h | 7 ++++++-
> include/vdso/bits.h | 2 +-
> 2 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/bits.h b/include/linux/bits.h
> index 0f559038981d..3dd32b9eef35 100644
> --- a/include/linux/bits.h
> +++ b/include/linux/bits.h
> @@ -2,7 +2,6 @@
> #ifndef __LINUX_BITS_H
> #define __LINUX_BITS_H
>
> -#include <vdso/bits.h>
> #include <uapi/linux/bits.h>
>
> #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
> @@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
> ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
> #endif /* defined(__ASSEMBLY__) */
>
> +/* Prefer this definition of BIT() to the one in vdso/bits.h */
> +#undef BIT
> +#define __VDSO_BITS_H
This is ugly.
Why can't the vDSO code make use of those checks, too?
Or use _BITUL() from the UAPI in the vDSO and remove vdso/bits.h.
> +#define BIT(nr) BIT_TYPE(unsigned long, nr)
> +#define BIT_ULL(nr) BIT_TYPE(unsigned long long, nr)
> #define BIT_U8(nr) BIT_TYPE(u8, nr)
> #define BIT_U16(nr) BIT_TYPE(u16, nr)
> #define BIT_U32(nr) BIT_TYPE(u32, nr)
> #define BIT_U64(nr) BIT_TYPE(u64, nr)
> +#define BIT_U128(nr) BIT_TYPE(u128, nr)
>
> #if defined(__ASSEMBLY__)
>
> diff --git a/include/vdso/bits.h b/include/vdso/bits.h
> index 388b212088ea..a6ac1e6b637c 100644
> --- a/include/vdso/bits.h
> +++ b/include/vdso/bits.h
> @@ -4,7 +4,7 @@
> > #include <vdso/const.h>
>
> +/* Most code picks up BIT() from linux/bits.h */
> #define BIT(nr) (UL(1) << (nr))
> -#define BIT_ULL(nr) (ULL(1) << (nr))
>
> #endif /* __VDSO_BITS_H */
> --
> 2.39.5
>
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
2026-01-21 15:17 ` Thomas Weißschuh
@ 2026-01-21 19:24 ` David Laight
2026-01-22 7:39 ` Thomas Weißschuh
0 siblings, 1 reply; 56+ messages in thread
From: David Laight @ 2026-01-21 19:24 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Wed, 21 Jan 2026 16:17:18 +0100
Thomas Weißschuh <thomas.weissschuh@linutronix.de> wrote:
> On Wed, Jan 21, 2026 at 02:57:29PM +0000, david.laight.linux@gmail.com wrote:
> > From: David Laight <david.laight.linux@gmail.com>
> >
> > The definition of BIT() was moved from linux/bits.h to vdso/bits.h to
> > isolate the vdso from 'normal' kernel headers.
> > BIT_ULL() was then moved to be defined in the same place for consistency.
> >
> > Since then linux/bits.h had gained BIT_Unn() and it really makes sense
> > for BIT() and BIT_ULL() to be defined in the same place.
> >
> > Move BIT_ULL() and make code that include both headers use the definition
> > of BIT() from linux/bits.h
> > Add BIT_U128() for completness.
> >
> > This lets BIT() pick up the extra compile time checks for W=[1c] builds
> > that detect errors like:
> > long foo(void) { int x = 64; return BIT(x); }
> > For which clang (silently) just generates a 'return' instruction.
> >
> > Note that nothing the the x86-64 build relies on the definition in
> > vdso/bits.h, linux/bits.h is always included.
> >
> > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> > ---
> > include/linux/bits.h | 7 ++++++-
> > include/vdso/bits.h | 2 +-
> > 2 files changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/linux/bits.h b/include/linux/bits.h
> > index 0f559038981d..3dd32b9eef35 100644
> > --- a/include/linux/bits.h
> > +++ b/include/linux/bits.h
> > @@ -2,7 +2,6 @@
> > #ifndef __LINUX_BITS_H
> > #define __LINUX_BITS_H
> >
> > -#include <vdso/bits.h>
> > #include <uapi/linux/bits.h>
> >
> > #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
> > @@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
> > ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
> > #endif /* defined(__ASSEMBLY__) */
> >
> > +/* Prefer this definition of BIT() to the one in vdso/bits.h */
> > +#undef BIT
> > +#define __VDSO_BITS_H
>
> This is ugly.
It works :-)
I could have put an #ifndef BIT in vdso/bits.h instead.
> Why can't the vDSO code make use of those checks, too?
> Or use _BITUL() from the UAPI in the vDSO and remove vdso/bits.h.
I didn't actually find anything that just needed vdso/bits.h
linux/bits.h would get included - eg (IIRC) because of warn_on_once().
I'm not that sure why it got separated, it isn't as though it defines
anything that is code version specific.
David
>
> > +#define BIT(nr) BIT_TYPE(unsigned long, nr)
> > +#define BIT_ULL(nr) BIT_TYPE(unsigned long long, nr)
> > #define BIT_U8(nr) BIT_TYPE(u8, nr)
> > #define BIT_U16(nr) BIT_TYPE(u16, nr)
> > #define BIT_U32(nr) BIT_TYPE(u32, nr)
> > #define BIT_U64(nr) BIT_TYPE(u64, nr)
> > +#define BIT_U128(nr) BIT_TYPE(u128, nr)
> >
> > #if defined(__ASSEMBLY__)
> >
> > diff --git a/include/vdso/bits.h b/include/vdso/bits.h
> > index 388b212088ea..a6ac1e6b637c 100644
> > --- a/include/vdso/bits.h
> > +++ b/include/vdso/bits.h
> > @@ -4,7 +4,7 @@
> > > #include <vdso/const.h>
> >
> > +/* Most code picks up BIT() from linux/bits.h */
> > #define BIT(nr) (UL(1) << (nr))
> > -#define BIT_ULL(nr) (ULL(1) << (nr))
> >
> > #endif /* __VDSO_BITS_H */
> > --
> > 2.39.5
> >
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
2026-01-21 19:24 ` David Laight
@ 2026-01-22 7:39 ` Thomas Weißschuh
0 siblings, 0 replies; 56+ messages in thread
From: Thomas Weißschuh @ 2026-01-22 7:39 UTC (permalink / raw)
To: David Laight
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Wed, Jan 21, 2026 at 07:24:51PM +0000, David Laight wrote:
> On Wed, 21 Jan 2026 16:17:18 +0100
> Thomas Weißschuh <thomas.weissschuh@linutronix.de> wrote:
>
> > On Wed, Jan 21, 2026 at 02:57:29PM +0000, david.laight.linux@gmail.com wrote:
> > > From: David Laight <david.laight.linux@gmail.com>
> > >
> > > The definition of BIT() was moved from linux/bits.h to vdso/bits.h to
> > > isolate the vdso from 'normal' kernel headers.
> > > BIT_ULL() was then moved to be defined in the same place for consistency.
> > >
> > > Since then linux/bits.h had gained BIT_Unn() and it really makes sense
> > > for BIT() and BIT_ULL() to be defined in the same place.
> > >
> > > Move BIT_ULL() and make code that include both headers use the definition
> > > of BIT() from linux/bits.h
> > > Add BIT_U128() for completness.
> > >
> > > This lets BIT() pick up the extra compile time checks for W=[1c] builds
> > > that detect errors like:
> > > long foo(void) { int x = 64; return BIT(x); }
> > > For which clang (silently) just generates a 'return' instruction.
> > >
> > > Note that nothing the the x86-64 build relies on the definition in
> > > vdso/bits.h, linux/bits.h is always included.
> > >
> > > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> > > ---
> > > include/linux/bits.h | 7 ++++++-
> > > include/vdso/bits.h | 2 +-
> > > 2 files changed, 7 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/include/linux/bits.h b/include/linux/bits.h
> > > index 0f559038981d..3dd32b9eef35 100644
> > > --- a/include/linux/bits.h
> > > +++ b/include/linux/bits.h
> > > @@ -2,7 +2,6 @@
> > > #ifndef __LINUX_BITS_H
> > > #define __LINUX_BITS_H
> > >
> > > -#include <vdso/bits.h>
> > > #include <uapi/linux/bits.h>
> > >
> > > #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
> > > @@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
> > > ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
> > > #endif /* defined(__ASSEMBLY__) */
> > >
> > > +/* Prefer this definition of BIT() to the one in vdso/bits.h */
> > > +#undef BIT
> > > +#define __VDSO_BITS_H
> >
> > This is ugly.
>
> It works :-)
> I could have put an #ifndef BIT in vdso/bits.h instead.
The #ifndef in vdso/bits.h is not much better IMO.
Given that there a multiple nicer options why not use on of those?
> > Why can't the vDSO code make use of those checks, too?
> > Or use _BITUL() from the UAPI in the vDSO and remove vdso/bits.h.
>
> I didn't actually find anything that just needed vdso/bits.h
> linux/bits.h would get included - eg (IIRC) because of warn_on_once().
That is a bug. The vdso code should only include the vdso/ namespace.
Right now the inclusions are all over the place. I'd like to clean that
up at some point.
> I'm not that sure why it got separated, it isn't as though it defines
> anything that is code version specific.
I don't understand "code version specific".
There are various issues with including normal kernel headers from the vDSO.
Symbols defined in terms of kconfig options, like BITS_PER_LONG using
CONFIG_64BIT are wrong in a compat vDSO.
> > > +#define BIT(nr) BIT_TYPE(unsigned long, nr)
> > > +#define BIT_ULL(nr) BIT_TYPE(unsigned long long, nr)
> > > #define BIT_U8(nr) BIT_TYPE(u8, nr)
> > > #define BIT_U16(nr) BIT_TYPE(u16, nr)
> > > #define BIT_U32(nr) BIT_TYPE(u32, nr)
> > > #define BIT_U64(nr) BIT_TYPE(u64, nr)
> > > +#define BIT_U128(nr) BIT_TYPE(u128, nr)
> > >
> > > #if defined(__ASSEMBLY__)
> > >
> > > diff --git a/include/vdso/bits.h b/include/vdso/bits.h
> > > index 388b212088ea..a6ac1e6b637c 100644
> > > --- a/include/vdso/bits.h
> > > +++ b/include/vdso/bits.h
> > > @@ -4,7 +4,7 @@
> > > > #include <vdso/const.h>
> > >
> > > +/* Most code picks up BIT() from linux/bits.h */
> > > #define BIT(nr) (UL(1) << (nr))
> > > -#define BIT_ULL(nr) (ULL(1) << (nr))
> > >
> > > #endif /* __VDSO_BITS_H */
> > > --
> > > 2.39.5
> > >
>
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
2026-01-21 14:57 ` [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h david.laight.linux
2026-01-21 15:17 ` Thomas Weißschuh
@ 2026-01-22 0:50 ` kernel test robot
2026-01-22 1:23 ` kernel test robot
2026-02-07 22:40 ` Thomas Gleixner
3 siblings, 0 replies; 56+ messages in thread
From: kernel test robot @ 2026-01-22 0:50 UTC (permalink / raw)
To: david.laight.linux, Nathan Chancellor, Greg Kroah-Hartman,
Thomas Gleixner, Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers,
Arnd Bergmann, linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton
Cc: llvm, oe-kbuild-all, Linux Memory Management List, David Laight
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on next-20260120]
url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
base: next-20260120
patch link: https://lore.kernel.org/r/20260121145731.3623-13-david.laight.linux%40gmail.com
patch subject: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
config: arm-allnoconfig (https://download.01.org/0day-ci/archive/20260122/202601220832.NJbHlnXC-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 9b8addffa70cee5b2acc5454712d9cf78ce45710)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220832.NJbHlnXC-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601220832.NJbHlnXC-lkp@intel.com/
All errors (new ones prefixed by >>):
163 | _SIG_SET_BINOP(sigandnsets, _sig_andn)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:139:8: note: expanded from macro '_SIG_SET_BINOP'
139 | b3 = b->sig[3]; b2 = b->sig[2]; \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:163:1: warning: array index 2 is past the end of the array (that has type 'const unsigned long[2]') [-Warray-bounds]
163 | _SIG_SET_BINOP(sigandnsets, _sig_andn)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:139:24: note: expanded from macro '_SIG_SET_BINOP'
139 | b3 = b->sig[3]; b2 = b->sig[2]; \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:163:1: warning: array index 3 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
163 | _SIG_SET_BINOP(sigandnsets, _sig_andn)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:140:3: note: expanded from macro '_SIG_SET_BINOP'
140 | r->sig[3] = op(a3, b3); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:163:1: warning: array index 2 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
163 | _SIG_SET_BINOP(sigandnsets, _sig_andn)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:141:3: note: expanded from macro '_SIG_SET_BINOP'
141 | r->sig[2] = op(a2, b2); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:187:1: warning: array index 3 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
187 | _SIG_SET_OP(signotset, _sig_not)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:174:27: note: expanded from macro '_SIG_SET_OP'
174 | case 4: set->sig[3] = op(set->sig[3]); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:187:1: warning: array index 3 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
187 | _SIG_SET_OP(signotset, _sig_not)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:174:10: note: expanded from macro '_SIG_SET_OP'
174 | case 4: set->sig[3] = op(set->sig[3]); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:187:1: warning: array index 2 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
187 | _SIG_SET_OP(signotset, _sig_not)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:175:20: note: expanded from macro '_SIG_SET_OP'
175 | set->sig[2] = op(set->sig[2]); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
In file included from include/linux/mm.h:36:
In file included from include/linux/rcuwait.h:6:
In file included from include/linux/sched/signal.h:6:
include/linux/signal.h:187:1: warning: array index 2 is past the end of the array (that has type 'unsigned long[2]') [-Warray-bounds]
187 | _SIG_SET_OP(signotset, _sig_not)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/signal.h:175:3: note: expanded from macro '_SIG_SET_OP'
175 | set->sig[2] = op(set->sig[2]); \
| ^ ~
arch/arm/include/asm/signal.h:17:2: note: array 'sig' declared here
17 | unsigned long sig[_NSIG_WORDS];
| ^
In file included from arch/arm/kernel/asm-offsets.c:14:
>> include/linux/mm.h:994:26: error: fields must have a constant size: 'variable length array in structure' extension will never be supported
994 | const vm_flags_t mask = BIT((__force int)bit);
| ^
include/linux/bits.h:94:18: note: expanded from macro 'BIT'
94 | #define BIT(nr) BIT_TYPE(unsigned long, nr)
| ^
include/linux/bits.h:88:17: note: expanded from macro 'BIT_TYPE'
88 | ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
| ^
include/linux/bits.h:82:24: note: expanded from macro 'BIT_INPUT_CHECK'
82 | sizeof(struct { char bit_number_too_big[-((nr) >= (width))];}), \
| ^
28 warnings and 16 errors generated.
make[3]: *** [scripts/Makefile.build:182: arch/arm/kernel/asm-offsets.s] Error 1
make[3]: Target 'prepare' not remade because of errors.
make[2]: *** [Makefile:1330: prepare0] Error 2
make[2]: Target 'prepare' not remade because of errors.
make[1]: *** [Makefile:248: __sub-make] Error 2
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:248: __sub-make] Error 2
make: Target 'prepare' not remade because of errors.
vim +994 include/linux/mm.h
bc292ab00f6c7a6 Suren Baghdasaryan 2023-01-26 990
568822502383acd Lorenzo Stoakes 2025-11-18 991 static inline bool __vma_flag_atomic_valid(struct vm_area_struct *vma,
2b6a3f061f11372 Lorenzo Stoakes 2025-11-25 992 vma_flag_t bit)
568822502383acd Lorenzo Stoakes 2025-11-18 993 {
2b6a3f061f11372 Lorenzo Stoakes 2025-11-25 @994 const vm_flags_t mask = BIT((__force int)bit);
568822502383acd Lorenzo Stoakes 2025-11-18 995
568822502383acd Lorenzo Stoakes 2025-11-18 996 /* Only specific flags are permitted */
568822502383acd Lorenzo Stoakes 2025-11-18 997 if (WARN_ON_ONCE(!(mask & VM_ATOMIC_SET_ALLOWED)))
568822502383acd Lorenzo Stoakes 2025-11-18 998 return false;
568822502383acd Lorenzo Stoakes 2025-11-18 999
568822502383acd Lorenzo Stoakes 2025-11-18 1000 return true;
568822502383acd Lorenzo Stoakes 2025-11-18 1001 }
568822502383acd Lorenzo Stoakes 2025-11-18 1002
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
2026-01-21 14:57 ` [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h david.laight.linux
2026-01-21 15:17 ` Thomas Weißschuh
2026-01-22 0:50 ` kernel test robot
@ 2026-01-22 1:23 ` kernel test robot
2026-01-22 10:30 ` David Laight
2026-02-07 22:40 ` Thomas Gleixner
3 siblings, 1 reply; 56+ messages in thread
From: kernel test robot @ 2026-01-22 1:23 UTC (permalink / raw)
To: david.laight.linux, Nathan Chancellor, Greg Kroah-Hartman,
Thomas Gleixner, Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers,
Arnd Bergmann, linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton
Cc: llvm, oe-kbuild-all, Linux Memory Management List, David Laight
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on next-20260120]
url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
base: next-20260120
patch link: https://lore.kernel.org/r/20260121145731.3623-13-david.laight.linux%40gmail.com
patch subject: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20260122/202601220951.7C4YG7hB-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220951.7C4YG7hB-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601220951.7C4YG7hB-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
In file included from kernel/bounds.c:14:
In file included from include/linux/log2.h:12:
In file included from include/linux/bitops.h:28:
In file included from include/asm-generic/bitops/generic-non-atomic.h:7:
In file included from arch/arm64/include/asm/barrier.h:14:
>> arch/arm64/include/asm/alternative-macros.h:18:20: warning: 'unsigned' is not defined, evaluates to 0 [-Wundef]
18 | #if ARM64_NCAPS >= ARM64_CB_BIT
| ^
arch/arm64/include/asm/alternative-macros.h:16:22: note: expanded from macro 'ARM64_CB_BIT'
16 | #define ARM64_CB_BIT BIT(ARM64_CB_SHIFT)
| ^
include/linux/bits.h:94:18: note: expanded from macro 'BIT'
94 | #define BIT(nr) BIT_TYPE(unsigned long, nr)
| ^
include/linux/bits.h:88:4: note: expanded from macro 'BIT_TYPE'
88 | ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
| ^
In file included from kernel/bounds.c:14:
In file included from include/linux/log2.h:12:
In file included from include/linux/bitops.h:28:
In file included from include/asm-generic/bitops/generic-non-atomic.h:7:
In file included from arch/arm64/include/asm/barrier.h:14:
>> arch/arm64/include/asm/alternative-macros.h:18:20: error: token is not a valid binary operator in a preprocessor subexpression
18 | #if ARM64_NCAPS >= ARM64_CB_BIT
| ^~~~~~~~~~~~
arch/arm64/include/asm/alternative-macros.h:16:22: note: expanded from macro 'ARM64_CB_BIT'
16 | #define ARM64_CB_BIT BIT(ARM64_CB_SHIFT)
| ^~~~~~~~~~~~~~~~~~~
include/linux/bits.h:94:18: note: expanded from macro 'BIT'
94 | #define BIT(nr) BIT_TYPE(unsigned long, nr)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/bits.h:88:13: note: expanded from macro 'BIT_TYPE'
88 | ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
| ~~~~~~~~ ^
1 warning and 1 error generated.
make[3]: *** [scripts/Makefile.build:182: kernel/bounds.s] Error 1
make[3]: Target 'prepare' not remade because of errors.
make[2]: *** [Makefile:1330: prepare0] Error 2
make[2]: Target 'prepare' not remade because of errors.
make[1]: *** [Makefile:248: __sub-make] Error 2
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:248: __sub-make] Error 2
make: Target 'prepare' not remade because of errors.
vim +18 arch/arm64/include/asm/alternative-macros.h
4c0bd995d73ed8 Mark Rutland 2022-09-12 17
4c0bd995d73ed8 Mark Rutland 2022-09-12 @18 #if ARM64_NCAPS >= ARM64_CB_BIT
4c0bd995d73ed8 Mark Rutland 2022-09-12 19 #error "cpucaps have overflown ARM64_CB_BIT"
4c0bd995d73ed8 Mark Rutland 2022-09-12 20 #endif
7cda23da52ad79 Will Deacon 2020-06-30 21
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
2026-01-22 1:23 ` kernel test robot
@ 2026-01-22 10:30 ` David Laight
0 siblings, 0 replies; 56+ messages in thread
From: David Laight @ 2026-01-22 10:30 UTC (permalink / raw)
To: kernel test robot
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Jani Nikula,
Vincent Mailhol, Andy Shevchenko, Kees Cook, Andrew Morton, llvm,
oe-kbuild-all, Linux Memory Management List
On Thu, 22 Jan 2026 09:23:16 +0800
kernel test robot <lkp@intel.com> wrote:
> Hi,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on next-20260120]
>
> url: https://github.com/intel-lab-lkp/linux/commits/david-laight-linux-gmail-com/overflow-Reduce-expansion-of-__type_max/20260122-013456
> base: next-20260120
> patch link: https://lore.kernel.org/r/20260121145731.3623-13-david.laight.linux%40gmail.com
> patch subject: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
> config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20260122/202601220951.7C4YG7hB-lkp@intel.com/config)
> compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260122/202601220951.7C4YG7hB-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202601220951.7C4YG7hB-lkp@intel.com/
>
> All error/warnings (new ones prefixed by >>):
>
> In file included from kernel/bounds.c:14:
> In file included from include/linux/log2.h:12:
> In file included from include/linux/bitops.h:28:
> In file included from include/asm-generic/bitops/generic-non-atomic.h:7:
> In file included from arch/arm64/include/asm/barrier.h:14:
> >> arch/arm64/include/asm/alternative-macros.h:18:20: warning: 'unsigned' is not defined, evaluates to 0 [-Wundef]
> 18 | #if ARM64_NCAPS >= ARM64_CB_BIT
...
>
> 4c0bd995d73ed8 Mark Rutland 2022-09-12 17
> 4c0bd995d73ed8 Mark Rutland 2022-09-12 @18 #if ARM64_NCAPS >= ARM64_CB_BIT
> 4c0bd995d73ed8 Mark Rutland 2022-09-12 19 #error "cpucaps have overflown ARM64_CB_BIT"
> 4c0bd995d73ed8 Mark Rutland 2022-09-12 20 #endif
> 7cda23da52ad79 Will Deacon 2020-06-30 21
Unless I change BIT() back I'll change that to a static_assert().
David
^ permalink raw reply [flat|nested] 56+ messages in thread
* Re: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
2026-01-21 14:57 ` [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h david.laight.linux
` (2 preceding siblings ...)
2026-01-22 1:23 ` kernel test robot
@ 2026-02-07 22:40 ` Thomas Gleixner
2026-02-08 4:23 ` Yury Norov
3 siblings, 1 reply; 56+ messages in thread
From: Thomas Gleixner @ 2026-02-07 22:40 UTC (permalink / raw)
To: david.laight.linux, Nathan Chancellor, Greg Kroah-Hartman,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
On Wed, Jan 21 2026 at 14:57, david laight linux wrote:
TLDR: Not going to happen. Period.
> Move BIT_ULL() and make code that include both headers use the definition
> of BIT() from linux/bits.h
> Add BIT_U128() for completness.
1) How is that related to $Subject?
2) It's clearly documented that patches should not do different things
at once.
3) It's also documented that stuff is only added when there is a use
case. I can't find one.
> Note that nothing the the x86-64 build relies on the definition in
> vdso/bits.h, linux/bits.h is always included.
Wrong. The x86-64 build includes vdso/bits.h for the VDSO build.
> @@ -2,7 +2,6 @@
> #ifndef __LINUX_BITS_H
> #define __LINUX_BITS_H
>
> -#include <vdso/bits.h>
> #include <uapi/linux/bits.h>
>
> #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
> @@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
> ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
> #endif /* defined(__ASSEMBLY__) */
>
> +/* Prefer this definition of BIT() to the one in vdso/bits.h */
> +#undef BIT
That's a horrible sloppy hack.
> +#define __VDSO_BITS_H
And this even more so.
> +#define BIT(nr) BIT_TYPE(unsigned long, nr)
> +#define BIT_ULL(nr) BIT_TYPE(unsigned long long, nr)
Aside of that you sloppily kept the comment above all of this intact,
which does not make any sense at all after this change. It says:
/*
* Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE(). The
* following examples generate compiler warnings due to -Wshift-count-overflow:
*
* - BIT_U8(8)
* - BIT_U32(-1)
* - BIT_U32(40)
*/
I have to admit that you are at least consistently sloppy.
> #define BIT_U8(nr) BIT_TYPE(u8, nr)
> #define BIT_U16(nr) BIT_TYPE(u16, nr)
> #define BIT_U32(nr) BIT_TYPE(u32, nr)
> #define BIT_U64(nr) BIT_TYPE(u64, nr)
> +#define BIT_U128(nr) BIT_TYPE(u128, nr)
What's wrong with the obvious solution of moving all this BIT_XX() muck
into vdso/bit.h?
Especially as you say in your changelog word salad:
> This lets BIT() pick up the extra compile time checks for W=[1c] builds
> that detect errors like:
> long foo(void) { int x = 64; return BIT(x); }
> For which clang (silently) just generates a 'return' instruction.
Letting the VDSO build have the same checks with a W=1 build would be
too sensible, right?
It's not rocket science to achieve that. See below.
That's admittedly a hack too, but a more palatable hack and I'm just
including it for illustration.
Just for the record: I definitely spent less time hacking that up than I
wasted reviewing and replying to your slop.
The proper thing to do is to move all the stuff which is neither vdso
nor kernel specific into a separate include/$BIKESHEDTHENAME/ directory
and sort out that ever recurring problem of VDSO vs. kernel builds once
and forever. That's not rocket science either.
That'd be too reasonable and tasteful, but not convoluted and sloppy
enough, right?
Thanks,
tglx
---
include/vdso/compiler.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/bits.h | 20 ------------
include/linux/compiler.h | 71 ------------------------------------------
include/vdso/bits.h | 23 ++++++++++++-
4 files changed, 97 insertions(+), 93 deletions(-)
---
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -9,8 +9,6 @@
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BIT_ULL_MASK(nr) (ULL(1) << ((nr) % BITS_PER_LONG_LONG))
#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG)
-#define BITS_PER_BYTE 8
-#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
/*
* Create a contiguous bitmask starting at bit position @l and ending at
@@ -57,24 +55,6 @@
#define GENMASK_U64(h, l) GENMASK_TYPE(u64, h, l)
#define GENMASK_U128(h, l) GENMASK_TYPE(u128, h, l)
-/*
- * Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE(). The
- * following examples generate compiler warnings due to -Wshift-count-overflow:
- *
- * - BIT_U8(8)
- * - BIT_U32(-1)
- * - BIT_U32(40)
- */
-#define BIT_INPUT_CHECK(type, nr) \
- BUILD_BUG_ON_ZERO(const_true((nr) >= BITS_PER_TYPE(type)))
-
-#define BIT_TYPE(type, nr) ((type)(BIT_INPUT_CHECK(type, nr) + BIT_ULL(nr)))
-
-#define BIT_U8(nr) BIT_TYPE(u8, nr)
-#define BIT_U16(nr) BIT_TYPE(u16, nr)
-#define BIT_U32(nr) BIT_TYPE(u32, nr)
-#define BIT_U64(nr) BIT_TYPE(u64, nr)
-
#else /* defined(__ASSEMBLY__) */
/*
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -279,53 +279,6 @@ static inline void *offset_to_ptr(const
___ADDRESSABLE(sym, __section(".discard.addressable"))
/*
- * This returns a constant expression while determining if an argument is
- * a constant expression, most importantly without evaluating the argument.
- * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de>
- *
- * Details:
- * - sizeof() return an integer constant expression, and does not evaluate
- * the value of its operand; it only examines the type of its operand.
- * - The results of comparing two integer constant expressions is also
- * an integer constant expression.
- * - The first literal "8" isn't important. It could be any literal value.
- * - The second literal "8" is to avoid warnings about unaligned pointers;
- * this could otherwise just be "1".
- * - (long)(x) is used to avoid warnings about 64-bit types on 32-bit
- * architectures.
- * - The C Standard defines "null pointer constant", "(void *)0", as
- * distinct from other void pointers.
- * - If (x) is an integer constant expression, then the "* 0l" resolves
- * it into an integer constant expression of value 0. Since it is cast to
- * "void *", this makes the second operand a null pointer constant.
- * - If (x) is not an integer constant expression, then the second operand
- * resolves to a void pointer (but not a null pointer constant: the value
- * is not an integer constant 0).
- * - The conditional operator's third operand, "(int *)8", is an object
- * pointer (to type "int").
- * - The behavior (including the return type) of the conditional operator
- * ("operand1 ? operand2 : operand3") depends on the kind of expressions
- * given for the second and third operands. This is the central mechanism
- * of the macro:
- * - When one operand is a null pointer constant (i.e. when x is an integer
- * constant expression) and the other is an object pointer (i.e. our
- * third operand), the conditional operator returns the type of the
- * object pointer operand (i.e. "int *"). Here, within the sizeof(), we
- * would then get:
- * sizeof(*((int *)(...)) == sizeof(int) == 4
- * - When one operand is a void pointer (i.e. when x is not an integer
- * constant expression) and the other is an object pointer (i.e. our
- * third operand), the conditional operator returns a "void *" type.
- * Here, within the sizeof(), we would then get:
- * sizeof(*((void *)(...)) == sizeof(void) == 1
- * - The equality comparison to "sizeof(int)" therefore depends on (x):
- * sizeof(int) == sizeof(int) (x) was a constant expression
- * sizeof(int) != sizeof(void) (x) was not a constant expression
- */
-#define __is_constexpr(x) \
- (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
-
-/*
* Whether 'type' is a signed type or an unsigned type. Supports scalar types,
* bool and also pointer types.
*/
@@ -342,28 +295,6 @@ static inline void *offset_to_ptr(const
#define statically_true(x) (__builtin_constant_p(x) && (x))
/*
- * Similar to statically_true() but produces a constant expression
- *
- * To be used in conjunction with macros, such as BUILD_BUG_ON_ZERO(),
- * which require their input to be a constant expression and for which
- * statically_true() would otherwise fail.
- *
- * This is a trade-off: const_true() requires all its operands to be
- * compile time constants. Else, it would always returns false even on
- * the most trivial cases like:
- *
- * true || non_const_var
- *
- * On the opposite, statically_true() is able to fold more complex
- * tautologies and will return true on expressions such as:
- *
- * !(non_const_var * 8 % 4)
- *
- * For the general case, statically_true() is better.
- */
-#define const_true(x) __builtin_choose_expr(__is_constexpr(x), x, false)
-
-/*
* This is needed in functions which generate the stack canary, see
* arch/x86/kernel/smpboot.c::start_secondary() for an example.
*/
--- a/include/vdso/bits.h
+++ b/include/vdso/bits.h
@@ -2,9 +2,26 @@
#ifndef __VDSO_BITS_H
#define __VDSO_BITS_H
+#include <vdso/compiler.h>
#include <vdso/const.h>
-#define BIT(nr) (UL(1) << (nr))
-#define BIT_ULL(nr) (ULL(1) << (nr))
+#if !defined(__ASSEMBLY__)
-#endif /* __VDSO_BITS_H */
+#define BITS_PER_BYTE 8
+#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
+
+/* Check for BIT() similar to GENMASK_TYPE() to catch shift count overflow at compile time */
+#define BIT_INPUT_CHECK(type, nr) \
+ BUILD_BUG_ON_ZERO(const_true((nr) >= BITS_PER_TYPE(type)))
+
+#define BIT_TYPE(type, nr) ((type)(BIT_INPUT_CHECK(type, nr) + (ULL(1) << (nr))))
+
+#define BIT(nr) BIT_TYPE(unsigned long, nr)
+#define BIT_ULL(nr) BIT_TYPE(unsigned long long, nr)
+#define BIT_U8(nr) BIT_TYPE(u8, nr)
+#define BIT_U16(nr) BIT_TYPE(u16, nr)
+#define BIT_U32(nr) BIT_TYPE(u32, nr)
+#define BIT_U64(nr) BIT_TYPE(u64, nr)
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __VDSO_BITS_H */
--- /dev/null
+++ b/include/vdso/compiler.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __VDSO_COMPILER_H
+#define __VDSO_COMPILER_H
+
+#include <linux/compiler_types.h>
+
+/*
+ * This returns a constant expression while determining if an argument is
+ * a constant expression, most importantly without evaluating the argument.
+ * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de>
+ *
+ * Details:
+ * - sizeof() return an integer constant expression, and does not evaluate
+ * the value of its operand; it only examines the type of its operand.
+ * - The results of comparing two integer constant expressions is also
+ * an integer constant expression.
+ * - The first literal "8" isn't important. It could be any literal value.
+ * - The second literal "8" is to avoid warnings about unaligned pointers;
+ * this could otherwise just be "1".
+ * - (long)(x) is used to avoid warnings about 64-bit types on 32-bit
+ * architectures.
+ * - The C Standard defines "null pointer constant", "(void *)0", as
+ * distinct from other void pointers.
+ * - If (x) is an integer constant expression, then the "* 0l" resolves
+ * it into an integer constant expression of value 0. Since it is cast to
+ * "void *", this makes the second operand a null pointer constant.
+ * - If (x) is not an integer constant expression, then the second operand
+ * resolves to a void pointer (but not a null pointer constant: the value
+ * is not an integer constant 0).
+ * - The conditional operator's third operand, "(int *)8", is an object
+ * pointer (to type "int").
+ * - The behavior (including the return type) of the conditional operator
+ * ("operand1 ? operand2 : operand3") depends on the kind of expressions
+ * given for the second and third operands. This is the central mechanism
+ * of the macro:
+ * - When one operand is a null pointer constant (i.e. when x is an integer
+ * constant expression) and the other is an object pointer (i.e. our
+ * third operand), the conditional operator returns the type of the
+ * object pointer operand (i.e. "int *"). Here, within the sizeof(), we
+ * would then get:
+ * sizeof(*((int *)(...)) == sizeof(int) == 4
+ * - When one operand is a void pointer (i.e. when x is not an integer
+ * constant expression) and the other is an object pointer (i.e. our
+ * third operand), the conditional operator returns a "void *" type.
+ * Here, within the sizeof(), we would then get:
+ * sizeof(*((void *)(...)) == sizeof(void) == 1
+ * - The equality comparison to "sizeof(int)" therefore depends on (x):
+ * sizeof(int) == sizeof(int) (x) was a constant expression
+ * sizeof(int) != sizeof(void) (x) was not a constant expression
+ */
+#define __is_constexpr(x) \
+ (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
+
+/*
+ * Similar to statically_true() but produces a constant expression
+ *
+ * To be used in conjunction with macros, such as BUILD_BUG_ON_ZERO(),
+ * which require their input to be a constant expression and for which
+ * statically_true() would otherwise fail.
+ *
+ * This is a trade-off: const_true() requires all its operands to be
+ * compile time constants. Else, it would always returns false even on
+ * the most trivial cases like:
+ *
+ * true || non_const_var
+ *
+ * On the opposite, statically_true() is able to fold more complex
+ * tautologies and will return true on expressions such as:
+ *
+ * !(non_const_var * 8 % 4)
+ *
+ * For the general case, statically_true() is better.
+ */
+#define const_true(x) __builtin_choose_expr(__is_constexpr(x), x, false)
+
+#endif
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h
2026-02-07 22:40 ` Thomas Gleixner
@ 2026-02-08 4:23 ` Yury Norov
0 siblings, 0 replies; 56+ messages in thread
From: Yury Norov @ 2026-02-08 4:23 UTC (permalink / raw)
To: Thomas Gleixner
Cc: david.laight.linux, Nathan Chancellor, Greg Kroah-Hartman,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Sat, Feb 07, 2026 at 11:40:41PM +0100, Thomas Gleixner wrote:
> On Wed, Jan 21 2026 at 14:57, david laight linux wrote:
>
> TLDR: Not going to happen. Period.
>
> > Move BIT_ULL() and make code that include both headers use the definition
> > of BIT() from linux/bits.h
> > Add BIT_U128() for completness.
>
> 1) How is that related to $Subject?
>
> 2) It's clearly documented that patches should not do different things
> at once.
>
> 3) It's also documented that stuff is only added when there is a use
> case. I can't find one.
>
> > Note that nothing the the x86-64 build relies on the definition in
> > vdso/bits.h, linux/bits.h is always included.
>
> Wrong. The x86-64 build includes vdso/bits.h for the VDSO build.
>
> > @@ -2,7 +2,6 @@
> > #ifndef __LINUX_BITS_H
> > #define __LINUX_BITS_H
> >
> > -#include <vdso/bits.h>
> > #include <uapi/linux/bits.h>
> >
> > #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
> > @@ -89,10 +88,16 @@ int BIT_INPUT_CHECK_FAIL(void) __compiletime_error("Bit number out of range");
> > ((unsigned int)BIT_INPUT_CHECK(+(nr), BITS_PER_TYPE(type)) + ((type)1 << (nr)))
> > #endif /* defined(__ASSEMBLY__) */
> >
> > +/* Prefer this definition of BIT() to the one in vdso/bits.h */
> > +#undef BIT
>
> That's a horrible sloppy hack.
>
> > +#define __VDSO_BITS_H
>
> And this even more so.
>
> > +#define BIT(nr) BIT_TYPE(unsigned long, nr)
> > +#define BIT_ULL(nr) BIT_TYPE(unsigned long long, nr)
>
> Aside of that you sloppily kept the comment above all of this intact,
> which does not make any sense at all after this change. It says:
>
> /*
> * Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE(). The
> * following examples generate compiler warnings due to -Wshift-count-overflow:
> *
> * - BIT_U8(8)
> * - BIT_U32(-1)
> * - BIT_U32(40)
> */
>
> I have to admit that you are at least consistently sloppy.
>
> > #define BIT_U8(nr) BIT_TYPE(u8, nr)
> > #define BIT_U16(nr) BIT_TYPE(u16, nr)
> > #define BIT_U32(nr) BIT_TYPE(u32, nr)
> > #define BIT_U64(nr) BIT_TYPE(u64, nr)
> > +#define BIT_U128(nr) BIT_TYPE(u128, nr)
>
> What's wrong with the obvious solution of moving all this BIT_XX() muck
> into vdso/bit.h?
>
> Especially as you say in your changelog word salad:
I'm next to that. I'm having hard times struggling through this
wording style. As a non-native English speaker, I used to ground
myself when I feel like I can't understand things. But here it's
clearly not only me.
David, for the next iteration, please reword your commit messages and
comments with a more standard version of English.
Regarding this patch, I agree with everything Thomas Gleixner and
Thomas Weißschuh said. This is an NAK.
> > This lets BIT() pick up the extra compile time checks for W=[1c] builds
> > that detect errors like:
> > long foo(void) { int x = 64; return BIT(x); }
> > For which clang (silently) just generates a 'return' instruction.
>
> Letting the VDSO build have the same checks with a W=1 build would be
> too sensible, right?
>
> It's not rocket science to achieve that. See below.
>
> That's admittedly a hack too, but a more palatable hack and I'm just
> including it for illustration.
>
> Just for the record: I definitely spent less time hacking that up than I
> wasted reviewing and replying to your slop.
>
> The proper thing to do is to move all the stuff which is neither vdso
> nor kernel specific into a separate include/$BIKESHEDTHENAME/ directory
> and sort out that ever recurring problem of VDSO vs. kernel builds once
> and forever. That's not rocket science either.
I would say, "both vdso and kernel", and I would probably add uapi in
the bucket.
Thanks,
Yury
> That'd be too reasonable and tasteful, but not convoluted and sloppy
> enough, right?
>
> Thanks,
>
> tglx
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH next 13/14] test_bits: Change all the tests to be compile-time tests
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (11 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 12/14] bits: move the defitions of BIT() and BIT_ULL() back to linux/bits.h david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
2026-02-08 4:37 ` Yury Norov
2026-01-21 14:57 ` [PATCH next 14/14] test_bits: include some invalid input tests for GENMASK_INPUT_CHECK() david.laight.linux
13 siblings, 1 reply; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
Since all the GENMASK() values are compile-time constants they can
be tested with BUILD_BUG_ON() rather than KUNIT_EXPECT_EQ().
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
lib/tests/test_bits.c | 90 +++++++++++++++++++++----------------------
1 file changed, 45 insertions(+), 45 deletions(-)
diff --git a/lib/tests/test_bits.c b/lib/tests/test_bits.c
index 36eb4661e78b..4d3a895f490c 100644
--- a/lib/tests/test_bits.c
+++ b/lib/tests/test_bits.c
@@ -32,30 +32,30 @@ static_assert(assert_type(u64, GENMASK_U64(63, 0)) == U64_MAX);
static void __genmask_test(struct kunit *test)
{
- KUNIT_EXPECT_EQ(test, 1ul, __GENMASK(0, 0));
- KUNIT_EXPECT_EQ(test, 3ul, __GENMASK(1, 0));
- KUNIT_EXPECT_EQ(test, 6ul, __GENMASK(2, 1));
- KUNIT_EXPECT_EQ(test, 0xFFFFFFFFul, __GENMASK(31, 0));
+ BUILD_BUG_ON(__GENMASK(0, 0) != 1ul);
+ BUILD_BUG_ON(__GENMASK(1, 0) != 3ul);
+ BUILD_BUG_ON(__GENMASK(2, 1) != 6ul);
+ BUILD_BUG_ON(__GENMASK(31, 0) != 0xFFFFFFFFul);
}
static void __genmask_ull_test(struct kunit *test)
{
- KUNIT_EXPECT_EQ(test, 1ull, __GENMASK_ULL(0, 0));
- KUNIT_EXPECT_EQ(test, 3ull, __GENMASK_ULL(1, 0));
- KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, __GENMASK_ULL(39, 21));
- KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, __GENMASK_ULL(63, 0));
+ BUILD_BUG_ON(__GENMASK_ULL(0, 0) != 1ull);
+ BUILD_BUG_ON(__GENMASK_ULL(1, 0) != 3ull);
+ BUILD_BUG_ON(__GENMASK_ULL(39, 21) != 0x000000ffffe00000ull);
+ BUILD_BUG_ON(__GENMASK_ULL(63, 0) != 0xffffffffffffffffull);
}
static void genmask_test(struct kunit *test)
{
- KUNIT_EXPECT_EQ(test, 1ul, GENMASK(0, 0));
- KUNIT_EXPECT_EQ(test, 3ul, GENMASK(1, 0));
- KUNIT_EXPECT_EQ(test, 6ul, GENMASK(2, 1));
- KUNIT_EXPECT_EQ(test, 0xFFFFFFFFul, GENMASK(31, 0));
+ BUILD_BUG_ON(GENMASK(0, 0) != 1ul);
+ BUILD_BUG_ON(GENMASK(1, 0) != 3ul);
+ BUILD_BUG_ON(GENMASK(2, 1) != 6ul);
+ BUILD_BUG_ON(GENMASK(31, 0) != 0xFFFFFFFFul);
- KUNIT_EXPECT_EQ(test, 1u, GENMASK_U8(0, 0));
- KUNIT_EXPECT_EQ(test, 3u, GENMASK_U16(1, 0));
- KUNIT_EXPECT_EQ(test, 0x10000, GENMASK_U32(16, 16));
+ BUILD_BUG_ON(GENMASK_U8(0, 0) != 1u);
+ BUILD_BUG_ON(GENMASK_U16(1, 0) != 3u);
+ BUILD_BUG_ON(GENMASK_U32(16, 16) != 0x10000);
#ifdef TEST_GENMASK_FAILURES
/* these should fail compilation */
@@ -75,10 +75,10 @@ static void genmask_test(struct kunit *test)
static void genmask_ull_test(struct kunit *test)
{
- KUNIT_EXPECT_EQ(test, 1ull, GENMASK_ULL(0, 0));
- KUNIT_EXPECT_EQ(test, 3ull, GENMASK_ULL(1, 0));
- KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, GENMASK_ULL(39, 21));
- KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_ULL(63, 0));
+ BUILD_BUG_ON(GENMASK_ULL(0, 0) != 1ull);
+ BUILD_BUG_ON(GENMASK_ULL(1, 0) != 3ull);
+ BUILD_BUG_ON(GENMASK_ULL(39, 21) != 0x000000ffffe00000ull);
+ BUILD_BUG_ON(GENMASK_ULL(63, 0) != 0xffffffffffffffffull);
#ifdef TEST_GENMASK_FAILURES
/* these should fail compilation */
@@ -92,23 +92,23 @@ static void genmask_u128_test(struct kunit *test)
{
#ifdef CONFIG_ARCH_SUPPORTS_INT128
/* Below 64 bit masks */
- KUNIT_EXPECT_EQ(test, 0x0000000000000001ull, GENMASK_U128(0, 0));
- KUNIT_EXPECT_EQ(test, 0x0000000000000003ull, GENMASK_U128(1, 0));
- KUNIT_EXPECT_EQ(test, 0x0000000000000006ull, GENMASK_U128(2, 1));
- KUNIT_EXPECT_EQ(test, 0x00000000ffffffffull, GENMASK_U128(31, 0));
- KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, GENMASK_U128(39, 21));
- KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(63, 0));
+ BUILD_BUG_ON(GENMASK_U128(0, 0) != 0x0000000000000001ull);
+ BUILD_BUG_ON(GENMASK_U128(1, 0) != 0x0000000000000003ull);
+ BUILD_BUG_ON(GENMASK_U128(2, 1) != 0x0000000000000006ull);
+ BUILD_BUG_ON(GENMASK_U128(31, 0) != 0x00000000ffffffffull);
+ BUILD_BUG_ON(GENMASK_U128(39, 21) != 0x000000ffffe00000ull);
+ BUILD_BUG_ON(GENMASK_U128(63, 0) != 0xffffffffffffffffull);
/* Above 64 bit masks - only 64 bit portion can be validated once */
- KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(64, 0) >> 1);
- KUNIT_EXPECT_EQ(test, 0x00000000ffffffffull, GENMASK_U128(81, 50) >> 50);
- KUNIT_EXPECT_EQ(test, 0x0000000000ffffffull, GENMASK_U128(87, 64) >> 64);
- KUNIT_EXPECT_EQ(test, 0x0000000000ff0000ull, GENMASK_U128(87, 80) >> 64);
-
- KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(127, 0) >> 64);
- KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, (u64)GENMASK_U128(127, 0));
- KUNIT_EXPECT_EQ(test, 0x0000000000000003ull, GENMASK_U128(127, 126) >> 126);
- KUNIT_EXPECT_EQ(test, 0x0000000000000001ull, GENMASK_U128(127, 127) >> 127);
+ BUILD_BUG_ON(GENMASK_U128(64, 0) >> 1 != 0xffffffffffffffffull);
+ BUILD_BUG_ON(GENMASK_U128(81, 50) >> 50 != 0x00000000ffffffffull);
+ BUILD_BUG_ON(GENMASK_U128(87, 64) >> 64 != 0x0000000000ffffffull);
+ BUILD_BUG_ON(GENMASK_U128(87, 80) >> 64 != 0x0000000000ff0000ull);
+
+ BUILD_BUG_ON(GENMASK_U128(127, 0) >> 64 != 0xffffffffffffffffull);
+ BUILD_BUG_ON((u64)GENMASK_U128(127, 0) != 0xffffffffffffffffull);
+ BUILD_BUG_ON(GENMASK_U128(127, 126) >> 126 != 0x0000000000000003ull);
+ BUILD_BUG_ON(GENMASK_U128(127, 127) >> 127 != 0x0000000000000001ull);
#ifdef TEST_GENMASK_FAILURES
/* these should fail compilation */
GENMASK_U128(0, 1);
@@ -129,21 +129,21 @@ static void genmask_input_check_test(struct kunit *test)
OPTIMIZER_HIDE_VAR(w);
/* Unknown input */
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, 0, 32));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, x, 32));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, y, 32));
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(x, 0, 32) != 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(0, x, 32) != 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(x, y, 32) != 0);
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, 0, 32));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, z, 32));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, w, 32));
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(z, 0, 32) != 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(0, z, 32) != 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(z, w, 32) != 0);
/* Valid input */
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(1, 1, 32));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(39, 21, 64));
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(1, 1, 32) != 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(39, 21, 64) != 0);
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(100, 80, 128));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(110, 65, 128));
- KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(127, 0, 128));
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(100, 80, 128) != 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(110, 65, 128) != 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(127, 0, 128) != 0);
}
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread* Re: [PATCH next 13/14] test_bits: Change all the tests to be compile-time tests
2026-01-21 14:57 ` [PATCH next 13/14] test_bits: Change all the tests to be compile-time tests david.laight.linux
@ 2026-02-08 4:37 ` Yury Norov
2026-02-08 11:32 ` David Laight
0 siblings, 1 reply; 56+ messages in thread
From: Yury Norov @ 2026-02-08 4:37 UTC (permalink / raw)
To: david.laight.linux
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Wed, Jan 21, 2026 at 02:57:30PM +0000, david.laight.linux@gmail.com wrote:
> From: David Laight <david.laight.linux@gmail.com>
>
> Since all the GENMASK() values are compile-time constants they can
> be tested with BUILD_BUG_ON() rather than KUNIT_EXPECT_EQ().
>
> Signed-off-by: David Laight <david.laight.linux@gmail.com>
I thought, KUNIT invented this EXPECT_EQ macro for a nice printing
and some accounting. If you want to make sure that __GENMASK() is a
compile-time expression, it's OK. But I'd rather keep the existing
KUNIT_EXPECT_EQ() and add
BUILD_BUG_ON(!__builtin_constant_p(GENMASK()))
next to that. This is actually how test_bitmap_const_eval() works.
Thanks,
Yury
> ---
> lib/tests/test_bits.c | 90 +++++++++++++++++++++----------------------
> 1 file changed, 45 insertions(+), 45 deletions(-)
>
> diff --git a/lib/tests/test_bits.c b/lib/tests/test_bits.c
> index 36eb4661e78b..4d3a895f490c 100644
> --- a/lib/tests/test_bits.c
> +++ b/lib/tests/test_bits.c
> @@ -32,30 +32,30 @@ static_assert(assert_type(u64, GENMASK_U64(63, 0)) == U64_MAX);
>
> static void __genmask_test(struct kunit *test)
> {
> - KUNIT_EXPECT_EQ(test, 1ul, __GENMASK(0, 0));
> - KUNIT_EXPECT_EQ(test, 3ul, __GENMASK(1, 0));
> - KUNIT_EXPECT_EQ(test, 6ul, __GENMASK(2, 1));
> - KUNIT_EXPECT_EQ(test, 0xFFFFFFFFul, __GENMASK(31, 0));
> + BUILD_BUG_ON(__GENMASK(0, 0) != 1ul);
> + BUILD_BUG_ON(__GENMASK(1, 0) != 3ul);
> + BUILD_BUG_ON(__GENMASK(2, 1) != 6ul);
> + BUILD_BUG_ON(__GENMASK(31, 0) != 0xFFFFFFFFul);
> }
>
> static void __genmask_ull_test(struct kunit *test)
> {
> - KUNIT_EXPECT_EQ(test, 1ull, __GENMASK_ULL(0, 0));
> - KUNIT_EXPECT_EQ(test, 3ull, __GENMASK_ULL(1, 0));
> - KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, __GENMASK_ULL(39, 21));
> - KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, __GENMASK_ULL(63, 0));
> + BUILD_BUG_ON(__GENMASK_ULL(0, 0) != 1ull);
> + BUILD_BUG_ON(__GENMASK_ULL(1, 0) != 3ull);
> + BUILD_BUG_ON(__GENMASK_ULL(39, 21) != 0x000000ffffe00000ull);
> + BUILD_BUG_ON(__GENMASK_ULL(63, 0) != 0xffffffffffffffffull);
> }
>
> static void genmask_test(struct kunit *test)
> {
> - KUNIT_EXPECT_EQ(test, 1ul, GENMASK(0, 0));
> - KUNIT_EXPECT_EQ(test, 3ul, GENMASK(1, 0));
> - KUNIT_EXPECT_EQ(test, 6ul, GENMASK(2, 1));
> - KUNIT_EXPECT_EQ(test, 0xFFFFFFFFul, GENMASK(31, 0));
> + BUILD_BUG_ON(GENMASK(0, 0) != 1ul);
> + BUILD_BUG_ON(GENMASK(1, 0) != 3ul);
> + BUILD_BUG_ON(GENMASK(2, 1) != 6ul);
> + BUILD_BUG_ON(GENMASK(31, 0) != 0xFFFFFFFFul);
>
> - KUNIT_EXPECT_EQ(test, 1u, GENMASK_U8(0, 0));
> - KUNIT_EXPECT_EQ(test, 3u, GENMASK_U16(1, 0));
> - KUNIT_EXPECT_EQ(test, 0x10000, GENMASK_U32(16, 16));
> + BUILD_BUG_ON(GENMASK_U8(0, 0) != 1u);
> + BUILD_BUG_ON(GENMASK_U16(1, 0) != 3u);
> + BUILD_BUG_ON(GENMASK_U32(16, 16) != 0x10000);
>
> #ifdef TEST_GENMASK_FAILURES
> /* these should fail compilation */
> @@ -75,10 +75,10 @@ static void genmask_test(struct kunit *test)
>
> static void genmask_ull_test(struct kunit *test)
> {
> - KUNIT_EXPECT_EQ(test, 1ull, GENMASK_ULL(0, 0));
> - KUNIT_EXPECT_EQ(test, 3ull, GENMASK_ULL(1, 0));
> - KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, GENMASK_ULL(39, 21));
> - KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_ULL(63, 0));
> + BUILD_BUG_ON(GENMASK_ULL(0, 0) != 1ull);
> + BUILD_BUG_ON(GENMASK_ULL(1, 0) != 3ull);
> + BUILD_BUG_ON(GENMASK_ULL(39, 21) != 0x000000ffffe00000ull);
> + BUILD_BUG_ON(GENMASK_ULL(63, 0) != 0xffffffffffffffffull);
>
> #ifdef TEST_GENMASK_FAILURES
> /* these should fail compilation */
> @@ -92,23 +92,23 @@ static void genmask_u128_test(struct kunit *test)
> {
> #ifdef CONFIG_ARCH_SUPPORTS_INT128
> /* Below 64 bit masks */
> - KUNIT_EXPECT_EQ(test, 0x0000000000000001ull, GENMASK_U128(0, 0));
> - KUNIT_EXPECT_EQ(test, 0x0000000000000003ull, GENMASK_U128(1, 0));
> - KUNIT_EXPECT_EQ(test, 0x0000000000000006ull, GENMASK_U128(2, 1));
> - KUNIT_EXPECT_EQ(test, 0x00000000ffffffffull, GENMASK_U128(31, 0));
> - KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, GENMASK_U128(39, 21));
> - KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(63, 0));
> + BUILD_BUG_ON(GENMASK_U128(0, 0) != 0x0000000000000001ull);
> + BUILD_BUG_ON(GENMASK_U128(1, 0) != 0x0000000000000003ull);
> + BUILD_BUG_ON(GENMASK_U128(2, 1) != 0x0000000000000006ull);
> + BUILD_BUG_ON(GENMASK_U128(31, 0) != 0x00000000ffffffffull);
> + BUILD_BUG_ON(GENMASK_U128(39, 21) != 0x000000ffffe00000ull);
> + BUILD_BUG_ON(GENMASK_U128(63, 0) != 0xffffffffffffffffull);
>
> /* Above 64 bit masks - only 64 bit portion can be validated once */
> - KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(64, 0) >> 1);
> - KUNIT_EXPECT_EQ(test, 0x00000000ffffffffull, GENMASK_U128(81, 50) >> 50);
> - KUNIT_EXPECT_EQ(test, 0x0000000000ffffffull, GENMASK_U128(87, 64) >> 64);
> - KUNIT_EXPECT_EQ(test, 0x0000000000ff0000ull, GENMASK_U128(87, 80) >> 64);
> -
> - KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(127, 0) >> 64);
> - KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, (u64)GENMASK_U128(127, 0));
> - KUNIT_EXPECT_EQ(test, 0x0000000000000003ull, GENMASK_U128(127, 126) >> 126);
> - KUNIT_EXPECT_EQ(test, 0x0000000000000001ull, GENMASK_U128(127, 127) >> 127);
> + BUILD_BUG_ON(GENMASK_U128(64, 0) >> 1 != 0xffffffffffffffffull);
> + BUILD_BUG_ON(GENMASK_U128(81, 50) >> 50 != 0x00000000ffffffffull);
> + BUILD_BUG_ON(GENMASK_U128(87, 64) >> 64 != 0x0000000000ffffffull);
> + BUILD_BUG_ON(GENMASK_U128(87, 80) >> 64 != 0x0000000000ff0000ull);
> +
> + BUILD_BUG_ON(GENMASK_U128(127, 0) >> 64 != 0xffffffffffffffffull);
> + BUILD_BUG_ON((u64)GENMASK_U128(127, 0) != 0xffffffffffffffffull);
> + BUILD_BUG_ON(GENMASK_U128(127, 126) >> 126 != 0x0000000000000003ull);
> + BUILD_BUG_ON(GENMASK_U128(127, 127) >> 127 != 0x0000000000000001ull);
> #ifdef TEST_GENMASK_FAILURES
> /* these should fail compilation */
> GENMASK_U128(0, 1);
> @@ -129,21 +129,21 @@ static void genmask_input_check_test(struct kunit *test)
> OPTIMIZER_HIDE_VAR(w);
>
> /* Unknown input */
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, 0, 32));
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, x, 32));
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, y, 32));
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(x, 0, 32) != 0);
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(0, x, 32) != 0);
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(x, y, 32) != 0);
>
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, 0, 32));
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, z, 32));
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, w, 32));
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(z, 0, 32) != 0);
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(0, z, 32) != 0);
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(z, w, 32) != 0);
>
> /* Valid input */
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(1, 1, 32));
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(39, 21, 64));
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(1, 1, 32) != 0);
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(39, 21, 64) != 0);
>
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(100, 80, 128));
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(110, 65, 128));
> - KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(127, 0, 128));
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(100, 80, 128) != 0);
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(110, 65, 128) != 0);
> + BUILD_BUG_ON(GENMASK_INPUT_CHECK(127, 0, 128) != 0);
> }
>
>
> --
> 2.39.5
^ permalink raw reply [flat|nested] 56+ messages in thread* Re: [PATCH next 13/14] test_bits: Change all the tests to be compile-time tests
2026-02-08 4:37 ` Yury Norov
@ 2026-02-08 11:32 ` David Laight
0 siblings, 0 replies; 56+ messages in thread
From: David Laight @ 2026-02-08 11:32 UTC (permalink / raw)
To: Yury Norov
Cc: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
On Sat, 7 Feb 2026 23:37:49 -0500
Yury Norov <ynorov@nvidia.com> wrote:
> On Wed, Jan 21, 2026 at 02:57:30PM +0000, david.laight.linux@gmail.com wrote:
> > From: David Laight <david.laight.linux@gmail.com>
> >
> > Since all the GENMASK() values are compile-time constants they can
> > be tested with BUILD_BUG_ON() rather than KUNIT_EXPECT_EQ().
> >
> > Signed-off-by: David Laight <david.laight.linux@gmail.com>
>
> I thought, KUNIT invented this EXPECT_EQ macro for a nice printing
> and some accounting. If you want to make sure that __GENMASK() is a
> compile-time expression, it's OK. But I'd rather keep the existing
> KUNIT_EXPECT_EQ() and add
>
> BUILD_BUG_ON(!__builtin_constant_p(GENMASK()))
>
> next to that. This is actually how test_bitmap_const_eval() works.
That just tests that the value is a compile time constant.
You want an error if the compile time constant is the wrong value.
The point is there is no reason to do a run-time check if the compile
test fails.
Making them compile-time means they get tested by the compiler,
so you don't need to run the tests at all.
The original tests in one of these files were all _Static_assert()
at file scope, but that requires 'integer constant expressions'.
They need moving into a function to use BUILD_BUG_ON().
Perhaps the test framework(s) should have a standard scheme for
compile-time tests.
David
>
> Thanks,
> Yury
>
> > ---
> > lib/tests/test_bits.c | 90 +++++++++++++++++++++----------------------
> > 1 file changed, 45 insertions(+), 45 deletions(-)
> >
> > diff --git a/lib/tests/test_bits.c b/lib/tests/test_bits.c
> > index 36eb4661e78b..4d3a895f490c 100644
> > --- a/lib/tests/test_bits.c
> > +++ b/lib/tests/test_bits.c
> > @@ -32,30 +32,30 @@ static_assert(assert_type(u64, GENMASK_U64(63, 0)) == U64_MAX);
> >
> > static void __genmask_test(struct kunit *test)
> > {
> > - KUNIT_EXPECT_EQ(test, 1ul, __GENMASK(0, 0));
> > - KUNIT_EXPECT_EQ(test, 3ul, __GENMASK(1, 0));
> > - KUNIT_EXPECT_EQ(test, 6ul, __GENMASK(2, 1));
> > - KUNIT_EXPECT_EQ(test, 0xFFFFFFFFul, __GENMASK(31, 0));
> > + BUILD_BUG_ON(__GENMASK(0, 0) != 1ul);
> > + BUILD_BUG_ON(__GENMASK(1, 0) != 3ul);
> > + BUILD_BUG_ON(__GENMASK(2, 1) != 6ul);
> > + BUILD_BUG_ON(__GENMASK(31, 0) != 0xFFFFFFFFul);
> > }
...
^ permalink raw reply [flat|nested] 56+ messages in thread
* [PATCH next 14/14] test_bits: include some invalid input tests for GENMASK_INPUT_CHECK()
2026-01-21 14:57 [PATCH next 00/14] bits: De-bloat expansion of GENMASK() david.laight.linux
` (12 preceding siblings ...)
2026-01-21 14:57 ` [PATCH next 13/14] test_bits: Change all the tests to be compile-time tests david.laight.linux
@ 2026-01-21 14:57 ` david.laight.linux
13 siblings, 0 replies; 56+ messages in thread
From: david.laight.linux @ 2026-01-21 14:57 UTC (permalink / raw)
To: Nathan Chancellor, Greg Kroah-Hartman, Thomas Gleixner,
Peter Zijlstra, Ingo Molnar, Mathieu Desnoyers, Arnd Bergmann,
linux-arch, linux-kernel, Yury Norov, Lucas De Marchi,
Jani Nikula, Vincent Mailhol, Andy Shevchenko, Kees Cook,
Andrew Morton
Cc: David Laight
From: David Laight <david.laight.linux@gmail.com>
The check for invalid 'compile time constant' parameters can easily be
changed to return 'failed' rather than generating a compile time error.
Add some tests for negative, swapped and overlarge values.
Signed-off-by: David Laight <david.laight.linux@gmail.com>
---
lib/tests/test_bits.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/lib/tests/test_bits.c b/lib/tests/test_bits.c
index 4d3a895f490c..9642c55f5487 100644
--- a/lib/tests/test_bits.c
+++ b/lib/tests/test_bits.c
@@ -144,6 +144,22 @@ static void genmask_input_check_test(struct kunit *test)
BUILD_BUG_ON(GENMASK_INPUT_CHECK(100, 80, 128) != 0);
BUILD_BUG_ON(GENMASK_INPUT_CHECK(110, 65, 128) != 0);
BUILD_BUG_ON(GENMASK_INPUT_CHECK(127, 0, 128) != 0);
+
+ /*
+ * Invalid input
+ * Change GENMASK_INPUT_CHECK() return 'fail' rather than
+ * generating a compile-time error.
+ */
+#define GENMASK_INPUT_CHECK_FAIL() 1
+ z = 0;
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(z + 31, -1, 32) == 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(z + 0, 1, 32) == 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(z + 8, 0, 8) == 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(z + 16, 0, 16) == 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(z + 32, 0, 32) == 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(z + 64, 0, 64) == 0);
+ BUILD_BUG_ON(GENMASK_INPUT_CHECK(z + 128, 0, 128) == 0);
+#undef GENMASK_INPUT_CHECK_FAIL
}
--
2.39.5
^ permalink raw reply related [flat|nested] 56+ messages in thread