* Re: [PATCH] printf: mark errptr() noinline
2026-04-05 17:31 [PATCH] printf: mark errptr() noinline Tamir Duberstein
@ 2026-04-05 18:17 ` Greg KH
2026-04-06 15:15 ` Steven Rostedt
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Greg KH @ 2026-04-05 18:17 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Petr Mladek, Steven Rostedt, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky, linux-kernel, stable, kernel test robot
On Sun, Apr 05, 2026 at 01:31:50PM -0400, Tamir Duberstein wrote:
> Old GCC can miscompile printf_kunit's errptr() test when branch
> profiling is enabled. BUILD_BUG_ON(IS_ERR(PTR)) is a constant false
> expression, but CONFIG_TRACE_BRANCH_PROFILING and
> CONFIG_PROFILE_ALL_BRANCHES make the IS_ERR() path side-effectful.
> GCC's IPA splitter can then outline the cold assert arm into
> errptr.part.* and leave that clone with an unconditional
> __compiletime_assert_*() call, causing a false build failure.
>
> This started showing up after test_hashed() became a macro and moved its
> local buffer into errptr(), which changed GCC's inlining and splitting
> decisions enough to expose the compiler bug.
>
> Mark errptr() noinline to keep it out of that buggy IPA path while
> preserving the BUILD_BUG_ON(IS_ERR(PTR)) check and the macro-based
> printf argument checking.
>
> Fixes: 9bfa52dac27a ("printf: convert test_hashed into macro")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202604030636.NqjaJvYp-lkp@intel.com/
> Signed-off-by: Tamir Duberstein <tamird@kernel.org>
> ---
> lib/tests/printf_kunit.c | 18 +++++++++++++++++-
> 1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/lib/tests/printf_kunit.c b/lib/tests/printf_kunit.c
> index f6f21b445ece..a8087e8ac826 100644
> --- a/lib/tests/printf_kunit.c
> +++ b/lib/tests/printf_kunit.c
> @@ -749,7 +749,23 @@ static void fourcc_pointer(struct kunit *kunittest)
> fourcc_pointer_test(kunittest, try_cb, ARRAY_SIZE(try_cb), "%p4cb");
> }
>
> -static void
> +/*
> + * GCC < 12.1 can miscompile this test when branch profiling is enabled.
> + *
> + * BUILD_BUG_ON(IS_ERR(PTR)) is a constant false expression, but old GCC can
> + * still trip over it after CONFIG_TRACE_BRANCH_PROFILING and
> + * CONFIG_PROFILE_ALL_BRANCHES rewrite the IS_ERR() unlikely() path into
> + * side-effectful branch counter updates. IPA splitting then outlines the cold
> + * assert arm into errptr.part.* and leaves that clone with an unconditional
> + * __compiletime_assert_*() call, so the build fails even though PTR is not an
> + * ERR_PTR.
> + *
> + * Keep this test out of that buggy IPA path so the BUILD_BUG_ON() can stay in
> + * place without open-coding IS_ERR(). This can be removed once the minimum GCC
> + * includes commit 76fe49423047 ("Fix tree-optimization/101941: IPA splitting
> + * out function with error attribute"), which first shipped in GCC 12.1.
> + */
> +static noinline void
> errptr(struct kunit *kunittest)
> {
> test("-1234", "%pe", ERR_PTR(-1234));
>
> ---
> base-commit: d8a9a4b11a137909e306e50346148fc5c3b63f9d
> change-id: 20260405-printf-test-old-gcc-f13fecda6524
>
> Best regards,
> --
> Tamir Duberstein <tamird@kernel.org>
>
>
<formletter>
This is not the correct way to submit patches for inclusion in the
stable kernel tree. Please read:
https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.
</formletter>
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH] printf: mark errptr() noinline
2026-04-05 17:31 [PATCH] printf: mark errptr() noinline Tamir Duberstein
2026-04-05 18:17 ` Greg KH
@ 2026-04-06 15:15 ` Steven Rostedt
2026-04-06 15:21 ` Tamir Duberstein
2026-04-06 16:40 ` Tamir Duberstein
2026-04-07 10:31 ` David Laight
3 siblings, 1 reply; 9+ messages in thread
From: Steven Rostedt @ 2026-04-06 15:15 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Petr Mladek, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky, linux-kernel, stable, kernel test robot
On Sun, 05 Apr 2026 13:31:50 -0400
Tamir Duberstein <tamird@kernel.org> wrote:
> Old GCC can miscompile printf_kunit's errptr() test when branch
> profiling is enabled. BUILD_BUG_ON(IS_ERR(PTR)) is a constant false
> expression, but CONFIG_TRACE_BRANCH_PROFILING and
> CONFIG_PROFILE_ALL_BRANCHES make the IS_ERR() path side-effectful.
> GCC's IPA splitter can then outline the cold assert arm into
> errptr.part.* and leave that clone with an unconditional
> __compiletime_assert_*() call, causing a false build failure.
>
> This started showing up after test_hashed() became a macro and moved its
> local buffer into errptr(), which changed GCC's inlining and splitting
> decisions enough to expose the compiler bug.
>
> Mark errptr() noinline to keep it out of that buggy IPA path while
> preserving the BUILD_BUG_ON(IS_ERR(PTR)) check and the macro-based
> printf argument checking.
>
> Fixes: 9bfa52dac27a ("printf: convert test_hashed into macro")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202604030636.NqjaJvYp-lkp@intel.com/
> Signed-off-by: Tamir Duberstein <tamird@kernel.org>
Another solution which I would be fine with is:
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index e130da35808f..c07e8eadfdd0 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -692,6 +692,7 @@ config PROFILE_ANNOTATED_BRANCHES
config PROFILE_ALL_BRANCHES
bool "Profile all if conditionals" if !FORTIFY_SOURCE
select TRACE_BRANCH_PROFILING
+ depends on !KUNIT
help
This tracer profiles all branch conditions. Every if ()
taken in the kernel is recorded whether it hit or miss.
-- Steve
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH] printf: mark errptr() noinline
2026-04-06 15:15 ` Steven Rostedt
@ 2026-04-06 15:21 ` Tamir Duberstein
2026-04-06 16:32 ` Steven Rostedt
0 siblings, 1 reply; 9+ messages in thread
From: Tamir Duberstein @ 2026-04-06 15:21 UTC (permalink / raw)
To: Steven Rostedt
Cc: Petr Mladek, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky, linux-kernel, stable, kernel test robot
On Mon, Apr 6, 2026 at 11:14 AM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Sun, 05 Apr 2026 13:31:50 -0400
> Tamir Duberstein <tamird@kernel.org> wrote:
>
> > Old GCC can miscompile printf_kunit's errptr() test when branch
> > profiling is enabled. BUILD_BUG_ON(IS_ERR(PTR)) is a constant false
> > expression, but CONFIG_TRACE_BRANCH_PROFILING and
> > CONFIG_PROFILE_ALL_BRANCHES make the IS_ERR() path side-effectful.
> > GCC's IPA splitter can then outline the cold assert arm into
> > errptr.part.* and leave that clone with an unconditional
> > __compiletime_assert_*() call, causing a false build failure.
> >
> > This started showing up after test_hashed() became a macro and moved its
> > local buffer into errptr(), which changed GCC's inlining and splitting
> > decisions enough to expose the compiler bug.
> >
> > Mark errptr() noinline to keep it out of that buggy IPA path while
> > preserving the BUILD_BUG_ON(IS_ERR(PTR)) check and the macro-based
> > printf argument checking.
> >
> > Fixes: 9bfa52dac27a ("printf: convert test_hashed into macro")
> > Reported-by: kernel test robot <lkp@intel.com>
> > Closes: https://lore.kernel.org/oe-kbuild-all/202604030636.NqjaJvYp-lkp@intel.com/
> > Signed-off-by: Tamir Duberstein <tamird@kernel.org>
>
> Another solution which I would be fine with is:
>
> diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
> index e130da35808f..c07e8eadfdd0 100644
> --- a/kernel/trace/Kconfig
> +++ b/kernel/trace/Kconfig
> @@ -692,6 +692,7 @@ config PROFILE_ANNOTATED_BRANCHES
> config PROFILE_ALL_BRANCHES
> bool "Profile all if conditionals" if !FORTIFY_SOURCE
> select TRACE_BRANCH_PROFILING
> + depends on !KUNIT
> help
> This tracer profiles all branch conditions. Every if ()
> taken in the kernel is recorded whether it hit or miss.
>
>
> -- Steve
Thanks Steve. IMO that is a very big hammer and not warranted in this
case. There's been talk of encouraging distros to enable CONFIG_KUNIT
by default [0], which would probably interact poorly with the change
you propose.
Link: https://lore.kernel.org/all/CABVgOS=KZrM2dWyp1HzVS0zh7vquLxmTY2T2Ti53DQADrW+sJg@mail.gmail.com/
[0]
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH] printf: mark errptr() noinline
2026-04-06 15:21 ` Tamir Duberstein
@ 2026-04-06 16:32 ` Steven Rostedt
2026-04-07 11:27 ` Petr Mladek
0 siblings, 1 reply; 9+ messages in thread
From: Steven Rostedt @ 2026-04-06 16:32 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Petr Mladek, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky, linux-kernel, stable, kernel test robot
On Mon, 6 Apr 2026 11:21:39 -0400
Tamir Duberstein <tamird@kernel.org> wrote:
> Thanks Steve. IMO that is a very big hammer and not warranted in this
> case. There's been talk of encouraging distros to enable CONFIG_KUNIT
> by default [0], which would probably interact poorly with the change
> you propose.
>
Branch profiling is really just a niche that is enabled specifically for
seeing all branches taken in the kernel. It hooks to all "if" statements!
As you can imagine, it causes a rather large overhead in performance.
This option is only used by developers doing special analysis of their code
(namely me ;-).
The only real concern I would have is if the kunit test developers would
want to use the branch profiling on their code, in which case my suggestion
would prevent that.
-- Steve
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] printf: mark errptr() noinline
2026-04-06 16:32 ` Steven Rostedt
@ 2026-04-07 11:27 ` Petr Mladek
2026-04-07 13:34 ` Tamir Duberstein
0 siblings, 1 reply; 9+ messages in thread
From: Petr Mladek @ 2026-04-07 11:27 UTC (permalink / raw)
To: Steven Rostedt
Cc: Tamir Duberstein, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky, linux-kernel, stable, kernel test robot
On Mon 2026-04-06 12:32:32, Steven Rostedt wrote:
> On Mon, 6 Apr 2026 11:21:39 -0400
> Tamir Duberstein <tamird@kernel.org> wrote:
>
> > Thanks Steve. IMO that is a very big hammer and not warranted in this
> > case. There's been talk of encouraging distros to enable CONFIG_KUNIT
> > by default [0], which would probably interact poorly with the change
> > you propose.
> >
>
> Branch profiling is really just a niche that is enabled specifically for
> seeing all branches taken in the kernel. It hooks to all "if" statements!
> As you can imagine, it causes a rather large overhead in performance.
>
> This option is only used by developers doing special analysis of their code
> (namely me ;-).
>
> The only real concern I would have is if the kunit test developers would
> want to use the branch profiling on their code, in which case my suggestion
> would prevent that.
I wonder if it might be possible to disable the branch profiling just
for the printf_kunit.c as a compromise.
Would "#undef if" in printf_kunit.c help?
Or I see that DISABLE_BRANCH_PROFILING is an official
way to disable the feature.
I wonder if the following change would solve the problem.
I am sorry, I could not test it easily.
diff --git a/lib/tests/Makefile b/lib/tests/Makefile
index 05f74edbc62b..45d69769ccdf 100644
--- a/lib/tests/Makefile
+++ b/lib/tests/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_MIN_HEAP_KUNIT_TEST) += min_heap_kunit.o
CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare)
obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o
+CFLAGS_printf_kunit.o += -DDISABLE_BRANCH_PROFILING
obj-$(CONFIG_RANDSTRUCT_KUNIT_TEST) += randstruct_kunit.o
obj-$(CONFIG_SCANF_KUNIT_TEST) += scanf_kunit.o
obj-$(CONFIG_SEQ_BUF_KUNIT_TEST) += seq_buf_kunit.o
Best Regards,
Petr
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] printf: mark errptr() noinline
2026-04-07 11:27 ` Petr Mladek
@ 2026-04-07 13:34 ` Tamir Duberstein
0 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2026-04-07 13:34 UTC (permalink / raw)
To: Petr Mladek
Cc: Steven Rostedt, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky, linux-kernel, stable, kernel test robot
On Tue, Apr 7, 2026 at 7:27 AM Petr Mladek <pmladek@suse.com> wrote:
>
> On Mon 2026-04-06 12:32:32, Steven Rostedt wrote:
> > On Mon, 6 Apr 2026 11:21:39 -0400
> > Tamir Duberstein <tamird@kernel.org> wrote:
> >
> > > Thanks Steve. IMO that is a very big hammer and not warranted in this
> > > case. There's been talk of encouraging distros to enable CONFIG_KUNIT
> > > by default [0], which would probably interact poorly with the change
> > > you propose.
> > >
> >
> > Branch profiling is really just a niche that is enabled specifically for
> > seeing all branches taken in the kernel. It hooks to all "if" statements!
> > As you can imagine, it causes a rather large overhead in performance.
> >
> > This option is only used by developers doing special analysis of their code
> > (namely me ;-).
> >
> > The only real concern I would have is if the kunit test developers would
> > want to use the branch profiling on their code, in which case my suggestion
> > would prevent that.
>
> I wonder if it might be possible to disable the branch profiling just
> for the printf_kunit.c as a compromise.
>
> Would "#undef if" in printf_kunit.c help?
>
> Or I see that DISABLE_BRANCH_PROFILING is an official
> way to disable the feature.
>
> I wonder if the following change would solve the problem.
> I am sorry, I could not test it easily.
Yes, we can disable it for the whole file. I decided against that
because narrow workarounds are better than broad ones IMO, but it is
ultimately up to your preference.
FWIW I did test that this patch fixes the problem in GCC 8.5.0.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] printf: mark errptr() noinline
2026-04-05 17:31 [PATCH] printf: mark errptr() noinline Tamir Duberstein
2026-04-05 18:17 ` Greg KH
2026-04-06 15:15 ` Steven Rostedt
@ 2026-04-06 16:40 ` Tamir Duberstein
2026-04-07 10:31 ` David Laight
3 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2026-04-06 16:40 UTC (permalink / raw)
To: Petr Mladek, Steven Rostedt, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky
Cc: linux-kernel, stable, kernel test robot
On Sun, Apr 5, 2026 at 1:32 PM Tamir Duberstein <tamird@kernel.org> wrote:
>
> Old GCC can miscompile printf_kunit's errptr() test when branch
> profiling is enabled. BUILD_BUG_ON(IS_ERR(PTR)) is a constant false
> expression, but CONFIG_TRACE_BRANCH_PROFILING and
> CONFIG_PROFILE_ALL_BRANCHES make the IS_ERR() path side-effectful.
> GCC's IPA splitter can then outline the cold assert arm into
> errptr.part.* and leave that clone with an unconditional
> __compiletime_assert_*() call, causing a false build failure.
>
> This started showing up after test_hashed() became a macro and moved its
> local buffer into errptr(), which changed GCC's inlining and splitting
> decisions enough to expose the compiler bug.
>
> Mark errptr() noinline to keep it out of that buggy IPA path while
> preserving the BUILD_BUG_ON(IS_ERR(PTR)) check and the macro-based
> printf argument checking.
>
> Fixes: 9bfa52dac27a ("printf: convert test_hashed into macro")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202604030636.NqjaJvYp-lkp@intel.com/
> Signed-off-by: Tamir Duberstein <tamird@kernel.org>
Adding tag per stable instructions:
Cc: stable@vger.kernel.org
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH] printf: mark errptr() noinline
2026-04-05 17:31 [PATCH] printf: mark errptr() noinline Tamir Duberstein
` (2 preceding siblings ...)
2026-04-06 16:40 ` Tamir Duberstein
@ 2026-04-07 10:31 ` David Laight
3 siblings, 0 replies; 9+ messages in thread
From: David Laight @ 2026-04-07 10:31 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Petr Mladek, Steven Rostedt, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky, linux-kernel, stable, kernel test robot
On Sun, 05 Apr 2026 13:31:50 -0400
Tamir Duberstein <tamird@kernel.org> wrote:
> Old GCC can miscompile printf_kunit's errptr() test when branch
> profiling is enabled. BUILD_BUG_ON(IS_ERR(PTR)) is a constant false
> expression, but CONFIG_TRACE_BRANCH_PROFILING and
> CONFIG_PROFILE_ALL_BRANCHES make the IS_ERR() path side-effectful.
> GCC's IPA splitter can then outline the cold assert arm into
> errptr.part.* and leave that clone with an unconditional
> __compiletime_assert_*() call, causing a false build failure.
>
> This started showing up after test_hashed() became a macro and moved its
> local buffer into errptr(), which changed GCC's inlining and splitting
> decisions enough to expose the compiler bug.
>
> Mark errptr() noinline to keep it out of that buggy IPA path while
> preserving the BUILD_BUG_ON(IS_ERR(PTR)) check and the macro-based
> printf argument checking.
Why not convert that check to a run-time one?
It isn't as though IS_ERR() is usually used with constants.
(There are a lot of other tests which would be better as compile-time
ones; since the run-time code just checks the compiler generated
the correct constant. So a compile failure saves you having to run
the tests; but that isn't true here.)
I'd also test -4095 and -4096...
>
> Fixes: 9bfa52dac27a ("printf: convert test_hashed into macro")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202604030636.NqjaJvYp-lkp@intel.com/
> Signed-off-by: Tamir Duberstein <tamird@kernel.org>
> ---
> lib/tests/printf_kunit.c | 18 +++++++++++++++++-
> 1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/lib/tests/printf_kunit.c b/lib/tests/printf_kunit.c
> index f6f21b445ece..a8087e8ac826 100644
> --- a/lib/tests/printf_kunit.c
> +++ b/lib/tests/printf_kunit.c
> @@ -749,7 +749,23 @@ static void fourcc_pointer(struct kunit *kunittest)
> fourcc_pointer_test(kunittest, try_cb, ARRAY_SIZE(try_cb), "%p4cb");
> }
>
> -static void
> +/*
> + * GCC < 12.1 can miscompile this test when branch profiling is enabled.
> + *
> + * BUILD_BUG_ON(IS_ERR(PTR)) is a constant false expression, but old GCC can
> + * still trip over it after CONFIG_TRACE_BRANCH_PROFILING and
> + * CONFIG_PROFILE_ALL_BRANCHES rewrite the IS_ERR() unlikely() path into
> + * side-effectful branch counter updates. IPA splitting then outlines the cold
> + * assert arm into errptr.part.* and leaves that clone with an unconditional
> + * __compiletime_assert_*() call, so the build fails even though PTR is not an
> + * ERR_PTR.
> + *
> + * Keep this test out of that buggy IPA path so the BUILD_BUG_ON() can stay in
> + * place without open-coding IS_ERR(). This can be removed once the minimum GCC
> + * includes commit 76fe49423047 ("Fix tree-optimization/101941: IPA splitting
> + * out function with error attribute"), which first shipped in GCC 12.1.
> + */
> +static noinline void
While that might make a difference, I'm not sure that it has to.
You aren't changing anything directly related to the failing expansion.
David
> errptr(struct kunit *kunittest)
> {
> test("-1234", "%pe", ERR_PTR(-1234));
>
> ---
> base-commit: d8a9a4b11a137909e306e50346148fc5c3b63f9d
> change-id: 20260405-printf-test-old-gcc-f13fecda6524
>
> Best regards,
> --
> Tamir Duberstein <tamird@kernel.org>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread