This series adds -fprofile-update=atomic to global CFLAGS_GCOV and
includes preparatory patches that fix build failures exposed by the new
flag.
Background
----------
This work combines and supersedes two previously separate series:
1. Build fix for CONFIG_GCOV_PROFILE_ALL=y - skb_ext_total_length()
BUILD_BUG_ON failure:
https://lore.kernel.org/lkml/20260331165125.959833-1-khorenko@virtuozzo.com/T/#t
2. Runtime crash fix for zlib inflate_fast() - GCOV counter merging
with loop induction variables caused out-of-bounds writes on SMP:
https://lore.kernel.org/lkml/20260330143256.306326-1-khorenko@virtuozzo.com/T/#t
The original zlib fix added -fprofile-update=atomic only to zlib
Makefiles. During review, it was suggested to apply the flag globally
instead, as it not only fixes the zlib crash but makes GCOV coverage
data more consistent overall. The GCC bug report for the underlying
compiler issue is at (and they also said just to use -fprofile-update=atomic):
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124749
Adding -fprofile-update=atomic to global CFLAGS_GCOV exposed two
additional build failures that are addressed by preparatory patches
in this series.
Series overview
---------------
Patch 1/4: net: fix skb_ext_total_length() BUILD_BUG_ON
Pre-existing build failure with CONFIG_GCOV_PROFILE_ALL=y. GCOV
counters prevent GCC from constant-folding the skb_ext_total_length()
loop. Fixed by adding __no_profile to the function and removing the
now-unnecessary CONFIG_KCOV_INSTRUMENT_ALL preprocessor guard.
(This is v2 of the previously posted standalone patch.)
Patch 2/4: net: add __no_profile to skb_extensions_init()
With -fprofile-update=atomic, __no_profile on skb_ext_total_length()
alone is insufficient - after __always_inline expansion the code
resides in the caller's body which still has GCOV instrumentation.
Mark the caller with __no_profile as well.
Patch 3/4: iommu/generic_pt: disable GCOV for iommu_amdv1.o
FIELD_PREP() compile-time checks fail because the entire call chain
is __always_inline functions generated by PT_MAKE_LEVELS() macro,
and GCC's .constprop cloning creates new profiled function bodies
that bypass __no_profile. Disable GCOV for this file.
Patch 4/4: gcov: use atomic counter updates to fix concurrent crashes
The main fix. Add -fprofile-update=atomic to CFLAGS_GCOV in the
top-level Makefile. This tells GCC to use atomic instructions for
GCOV counter updates, preventing the compiler from merging counters
with loop induction variables. This fixes observed crashes in zlib's
inflate_fast() during concurrent IPComp decompression and makes GCOV
data reliable across the entire kernel on SMP systems.
The crash that motivated this work
-----------------------------------
Observed during LTP IPComp stress testing on a GCOV-enabled kernel:
BUG: unable to handle page fault for address: ffffd0a3c0902ffa
RIP: inflate_fast+1431
Call Trace:
zlib_inflate
__deflate_decompress
crypto_comp_decompress
ipcomp_decompress [xfrm_ipcomp]
ipcomp_input [xfrm_ipcomp]
xfrm_input
GCC merged a global GCOV counter with the loop induction variable.
Another CPU modified the counter between loads, causing a write 3.4 MB
past a 65 KB buffer. -fprofile-update=atomic forces atomic counter
updates and prevents this merging.
Testing
-------
- Build-tested with CONFIG_GCOV_PROFILE_ALL=y using GCC 11.4.1 and
GCC 16.0.1 20260327 (experimental). Both fail without the series,
both succeed with the full series applied.
- Assembly-verified that -fprofile-update=atomic prevents counter-IV
merging in inflate_fast() on both compiler versions.
Konstantin Khorenko (4):
net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL
net: add __no_profile to skb_extensions_init() for GCOV compatibility
iommu/generic_pt: disable GCOV for iommu_amdv1.o
gcov: use atomic counter updates to fix concurrent access crashes
Makefile | 2 +-
drivers/iommu/generic_pt/fmt/Makefile | 2 ++
net/core/skbuff.c | 5 ++---
3 files changed, 5 insertions(+), 4 deletions(-)
--
2.43.5