Linux kbuild/kconfig development
 help / color / mirror / Atom feed
* [PATCH v3 0/1] gcov: use -fprofile-update=prefer-atomic with compile-time guard
@ 2026-05-09 14:22 Konstantin Khorenko
  2026-05-09 14:22 ` [PATCH v3 1/1] gcov: use atomic counter updates to fix concurrent access crashes Konstantin Khorenko
  0 siblings, 1 reply; 2+ messages in thread
From: Konstantin Khorenko @ 2026-05-09 14:22 UTC (permalink / raw)
  To: Andrew Morton, Arnd Bergmann, Peter Oberparleiter
  Cc: Nathan Chancellor, Nicolas Schier, Mikhail Zaslonko,
	Thomas Weißschuh, Miguel Ojeda, Masahiro Yamada,
	Vasileios Almpanis, Pavel Tikhomirov, linux-kernel, linux-kbuild,
	Konstantin Khorenko

This is v3 of the patch to add -fprofile-update=prefer-atomic to
CFLAGS_GCOV.

v2 was reported to cause link failures on some architecture/config
combinations because GCC emits calls to libatomic runtime functions
for 64-bit atomic counter increments, and the kernel does not link
against libatomic:

  https://lore.kernel.org/all/ff2a4c49-463d-4d8a-9519-bb51308f7ba1@linux.ibm.com/

Arnd Bergmann hit this with GCC-16 randconfig builds:

  x86_64:  undefined reference to `__atomic_fetch_add_8'
  aarch64: undefined reference to `__aarch64_ldadd8_relax'

The kernel test robot confirmed the same on i386-allmodconfig with
GCC 14 (Debian):

  https://lore.kernel.org/all/202605030611.mBKmkPOF-lkp@intel.com/

v3 adds a compile-time try-run check that determines whether
-fprofile-update=prefer-atomic is safe to use with the current
compiler and architecture.

=== Approach ===

The check compiles a minimal test program twice using the full
KBUILD_CFLAGS -- once without and once with -fprofile-update=prefer-atomic
-- then compares the undefined symbols in both resulting .o files using
nm.  If prefer-atomic introduces any NEW undefined symbols, the flag is
not added.

Several alternative approaches were considered and rejected:

1) Grepping assembly output for known libatomic symbols
   (__atomic_fetch_add, __aarch64_ldadd, etc):
   Fragile -- requires maintaining a list of arch-specific symbol names.
   New architectures or GCC versions may use different names.

2) Checking nm output for any undefined symbol beyond __gcov_*:
   Fails because KBUILD_CFLAGS adds kernel-specific instrumentation
   (__fentry__, __x86_return_thunk, etc) that creates "expected"
   undefined symbols unrelated to libatomic.

3) Grepping only for "__atomic" in undefined symbols:
   Misses aarch64 outline-atomics symbols (__aarch64_ldadd8_relax)
   which do not contain "atomic" in their name.

4) Filtering KBUILD_CFLAGS to pass only -m32/-m64/-march=* to try-run:
   Brittle whitelist -- misses flags like -mno-outline-atomics on arm64
   and will break when new relevant flags are added.

The chosen diff-based approach is fully architecture-agnostic: it uses
the real KBUILD_CFLAGS, does not depend on knowing libatomic symbol
names, and will not break when new flags or architectures are added.
The only assumption is that -fprofile-update=prefer-atomic should not
introduce any new linker dependencies.

Also, the CFLAGS_GCOV block is moved after the final KBUILD_CFLAGS
assignments so the try-run test sees the complete set of compiler flags.

=== Testing ===

Verified on:
  - x86_64, GCC 17.0.0 (trunk 2026-05-09): flag IS added, inline
    lock addq for GCOV counters
  - arm64 cross-compile, GCC 14.1.1 (aarch64-linux-gnu-gcc):
    flag is NOT added (__aarch64_ldadd8_relax detected)

arm64 example showing the try-run detection in action:

  $ echo 'long long x; void f(void){x++;}' | \
    aarch64-linux-gnu-gcc [KBUILD_CFLAGS] -fprofile-arcs \
    -ftest-coverage -c -o base.o
  $ nm base.o | grep ' U '
                   U __gcov_exit
                   U __gcov_init
                   U __gcov_merge_add

  $ echo 'long long x; void f(void){x++;}' | \
    aarch64-linux-gnu-gcc [KBUILD_CFLAGS] -fprofile-arcs \
    -ftest-coverage -fprofile-update=prefer-atomic -c -o test.o
  $ nm test.o | grep ' U '
                   U __aarch64_ldadd8_relax   <-- new, from libatomic
                   U __gcov_exit
                   U __gcov_init
                   U __gcov_merge_add

  The undefined symbols differ => try-run fails => flag not added.

Changes since v2:
  - Added try-run compile-time check (option 3 from Peter's proposal)
  - Moved CFLAGS_GCOV definition after KBUILD_CFLAGS is finalized
  - Split -fprofile-update=prefer-atomic from -fno-tree-loop-im

Konstantin Khorenko (1):
  gcov: use atomic counter updates to fix concurrent access crashes

 Makefile | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

-- 
2.47.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-05-09 14:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-09 14:22 [PATCH v3 0/1] gcov: use -fprofile-update=prefer-atomic with compile-time guard Konstantin Khorenko
2026-05-09 14:22 ` [PATCH v3 1/1] gcov: use atomic counter updates to fix concurrent access crashes Konstantin Khorenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox