From: Peter Zijlstra <peterz@infradead.org>
To: Sasha Levin <sashal@kernel.org>
Cc: linux-kernel@vger.kernel.org, Bill Wendling <morbo@google.com>,
Chuck Wolber <chuck@wolber.net>,
Justin Stitt <justinstitt@google.com>,
llvm@lists.linux.dev, Marco Elver <elver@google.com>,
Masami Hiramatsu <mhiramat@kernel.org>,
Miguel Ojeda <ojeda@kernel.org>,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Thomas Gleixner <tglx@kernel.org>,
wentaoz5@illinois.edu, chuck.wolber@boeing.com,
steven.h.vanderleest@boeing.com
Subject: Re: [RFC PATCH 04/20] compiler_types.h: Don't instrument __always_inline functions for coverage
Date: Wed, 28 Oct 2026 14:51:40 +0100 [thread overview]
Message-ID: <20261028135140.GR2668564@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <20261028120034.871983-5-sashal@kernel.org>
On Wed, Oct 28, 2026 at 07:59:28AM -0400, Sasha Levin wrote:
> noinstr code may only call other noinstr functions and __always_inline
> functions. gcov and Clang's source-based code coverage insert their
> instrumentation before inlining, so the instrumentation of an
> __always_inline function ends up in every noinstr function it gets
> inlined into. With Clang's source-based coverage on x86, 2500 of the
> 3449 relocations in .noinstr.text and 333 of the 451 in .cpuidle.text
> of vmlinux.o point to coverage counters or MC/DC bitmaps. GCC's gcov
> does the same. Since these are plain memory updates rather than calls,
> objtool's noinstr validation doesn't notice them.
>
> KCOV doesn't have this problem, as it instruments the code after
> inlining and checks the attributes of the function that the code ends
> up in.
>
> Make __always_inline imply __no_profile when a code coverage
> measurement implementation is enabled, so that no noinstr code carries
> coverage instrumentation. The cost is that __always_inline functions
> don't show up in the coverage data at all, including at their callers
> outside of noinstr code. For an x86_64 configuration built with Clang 22
> and MC/DC, that removes 556 of 60788 functions (0.9%), 29261 of 1598305
> regions (1.8%), 11067 of 591108 branches (1.9%) and 445 of 36561 MC/DC
> conditions (1.2%) from the coverage data.
This is pretty vile. But also, since people were trying to use MC/DC for
validation efforts and the like, how does this impact them? If I
understand correctly their previous emails on the topic, this means they
have to go manually audit every single __always_inline function.
Now; I understand this is a tool limitation and there really must not be
instrumentation in noinstr code, since that can run before things like
page-tables are complete (consider the PTI case). So this is the best
option.
Still, I'm left wondering if these tools should be fixed. For instance,
while the front-end emits this instrumentation, the backend could easily
remove it again when it finds itself in the context of a noinstr
function after inlining.
> Leave unoptimized objects alone: GCC refuses to inline an
> __always_inline function across a no_profile_instrument_function
> mismatch at -O0, and those objects don't contain noinstr code.
We have -O0 code? I thought we hard relied on building with at least
-O1, we often get 'fixes' to enable code to build with -O0.
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> include/linux/compiler_types.h | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
> index c5921f1390079..c3298d29a9425 100644
> --- a/include/linux/compiler_types.h
> +++ b/include/linux/compiler_types.h
> @@ -246,6 +246,19 @@ struct ftrace_likely_data {
> */
> #define __inline__ inline
>
> +/*
> + * noinstr code may only call noinstr and __always_inline functions. Code
> + * coverage instrumentation is added before inlining, so the counters of an
> + * __always_inline function would end up in the noinstr code it gets inlined
> + * into: don't instrument __always_inline functions. GCC refuses to inline
> + * across a no_profile_instrument_function mismatch without optimization, so
> + * leave the rare unoptimized objects alone; they don't contain noinstr code.
> + */
> +#if defined(CONFIG_COVERAGE_KERNEL) && defined(__OPTIMIZE__)
> +#undef __always_inline
> +#define __always_inline inline __attribute__((__always_inline__)) __no_profile
> +#endif
> +
> /*
> * GCC does not warn about unused static inline functions for -Wunused-function.
> * Suppress the warning in clang as well by using __maybe_unused, but enable it
> --
> 2.53.0
>
next prev parent reply other threads:[~2026-10-28 13:51 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 11:59 [RFC PATCH 00/20] Unify code coverage and add Clang source-based coverage with MC/DC Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 01/20] coverage: move gcov and kcov under kernel/coverage/ Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 02/20] kbuild: unify static coverage instrumentation as COVERAGE_PROFILE Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 04/20] compiler_types.h: Don't instrument __always_inline functions for coverage Sasha Levin
2026-10-28 13:51 ` Peter Zijlstra [this message]
2026-10-28 14:01 ` Peter Zijlstra
2026-10-28 16:45 ` Sasha Levin
2026-10-29 5:49 ` Chuck Wolber
2026-10-28 11:59 ` [RFC PATCH 07/20] perf: Always inline the empty perf_lopwr_cb() stub Sasha Levin
2026-10-29 12:01 ` sashiko-bot
2026-10-28 11:59 ` [RFC PATCH 10/20] x86/sev: Use non-instrumented bitops in the GHCB accessors Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 11/20] objtool: Detect code coverage instrumentation in noinstr code Sasha Levin
2026-10-28 14:11 ` Peter Zijlstra
2026-10-28 16:45 ` Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 12/20] x86/sev: Stop excluding noinstr.o from code coverage Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 14/20] coverage: add Clang's source-based " Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 15/20] x86: Enable " Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 16/20] coverage: add MC/DC measurement Sasha Levin
2026-10-28 19:14 ` Nathan Chancellor
2026-10-28 20:39 ` Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 18/20] kconfig: add CC_HAS_CONDITION_COVERAGE for MC/DC support detection Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 19/20] gcov: add MC/DC condition coverage support Sasha Levin
2026-10-28 11:59 ` [RFC PATCH 20/20] Documentation: dev-tools: document the common code coverage interface Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261028135140.GR2668564@noisy.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=chuck.wolber@boeing.com \
--cc=chuck@wolber.net \
--cc=elver@google.com \
--cc=justinstitt@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=mhiramat@kernel.org \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=ojeda@kernel.org \
--cc=sashal@kernel.org \
--cc=steven.h.vanderleest@boeing.com \
--cc=tglx@kernel.org \
--cc=wentaoz5@illinois.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.