* [PATCH 0/1] gcov: add -fprofile-update=atomic to fix concurrent access crashes @ 2026-04-02 14:18 Konstantin Khorenko 2026-04-02 14:18 ` [PATCH] gcov: use atomic counter updates " Konstantin Khorenko 0 siblings, 1 reply; 4+ messages in thread From: Konstantin Khorenko @ 2026-04-02 14:18 UTC (permalink / raw) To: Peter Oberparleiter, Mikhail Zaslonko, Nathan Chancellor, Nicolas Schier Cc: Masahiro Yamada, Thomas Weißschuh, Arnd Bergmann, Steffen Klassert, Herbert Xu, linux-kbuild, linux-kernel, netdev, Konstantin Khorenko, Pavel Tikhomirov, Vasileios Almpanis, Jakub Kicinski This patch adds -fprofile-update=atomic to global CFLAGS_GCOV in the top-level Makefile to fix crashes caused by GCC merging GCOV counters with loop induction variables in concurrent code paths. History ------- This was originally posted as a zlib-only fix: https://lore.kernel.org/lkml/20260330143256.306326-1-khorenko@virtuozzo.com/T/#t During review, it was suggested to apply the flag globally instead of per-subsystem, as it not only fixes the observed crash but makes GCOV coverage data more consistent overall. A combined series was posted: https://lore.kernel.org/lkml/20260401142020.1434243-1-khorenko@virtuozzo.com/T/#t That combined series is now split per subsystem as requested by reviewers. The GCC bug report for the underlying compiler issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124749 Dependencies ------------ This patch requires the following preparatory fixes to be applied first, otherwise CONFIG_GCOV_PROFILE_ALL=y builds will fail: - net: fix skb_ext BUILD_BUG_ON failures with GCOV (sent to netdev): __no_profile on skb_ext_total_length() and skb_extensions_init() https://lore.kernel.org/lkml/20260402140558.1437002-1-khorenko@virtuozzo.com/T/#t - iommu/generic_pt: disable GCOV for iommu_amdv1.o (sent to iommu): GCOV_PROFILE_iommu_amdv1.o := n https://lore.kernel.org/lkml/20260402141012.1437095-1-khorenko@virtuozzo.com/T/#t Without those patches, -fprofile-update=atomic prevents GCC from constant-folding expressions inside profiled inline functions, breaking BUILD_BUG_ON / FIELD_PREP compile-time checks. The crash --------- 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 full set of patches, both succeed with all three series applied. Assembly-verified that -fprofile-update=atomic prevents counter-IV merging in inflate_fast() on both compiler versions. Also tested by Peter Oberparleiter: Quote: "Successfully tested this series on s390 (except for patch 3 which depends on x86) using GCC 15.2.0, GCC 10.1.0, and current Clang from git (20260401)." Konstantin Khorenko (1): gcov: use atomic counter updates to fix concurrent access crashes Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.43.5 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] gcov: use atomic counter updates to fix concurrent access crashes 2026-04-02 14:18 [PATCH 0/1] gcov: add -fprofile-update=atomic to fix concurrent access crashes Konstantin Khorenko @ 2026-04-02 14:18 ` Konstantin Khorenko 2026-04-06 19:37 ` Nathan Chancellor 0 siblings, 1 reply; 4+ messages in thread From: Konstantin Khorenko @ 2026-04-02 14:18 UTC (permalink / raw) To: Peter Oberparleiter, Mikhail Zaslonko, Nathan Chancellor, Nicolas Schier Cc: Masahiro Yamada, Thomas Weißschuh, Arnd Bergmann, Steffen Klassert, Herbert Xu, linux-kbuild, linux-kernel, netdev, Konstantin Khorenko, Pavel Tikhomirov, Vasileios Almpanis, Jakub Kicinski GCC's GCOV instrumentation can merge global branch counters with loop induction variables as an optimization. In inflate_fast(), the inner copy loops get transformed so that the GCOV counter value is loaded multiple times to compute the loop base address, start index, and end bound. Since GCOV counters are global (not per-CPU), concurrent execution on different CPUs causes the counter to change between loads, producing inconsistent values and out-of-bounds memory writes. The crash manifests during IPComp (IP Payload Compression) processing when inflate_fast() runs concurrently on multiple CPUs: 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 At the crash point, the compiler generated three loads from the same global GCOV counter (__gcov0.inflate_fast+216) to compute base, start, and end for an indexed loop. Another CPU modified the counter between loads, making the values inconsistent — the write went 3.4 MB past a 65 KB buffer. Add -fprofile-update=atomic to CFLAGS_GCOV at the global level in the top-level Makefile. This tells GCC that GCOV counters may be concurrently accessed, causing counter updates to use atomic instructions (lock addq) instead of plain load/store. This prevents the compiler from merging counters with loop induction variables. Applying this globally rather than per-subsystem not only addresses the observed crash in zlib but makes GCOV coverage data more consistent overall, preventing similar issues in any kernel code path that may execute concurrently. Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> Tested-by: Peter Oberparleiter <oberpar@linux.ibm.com> Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6b1d9fb1a6b4..a55ad668d6ba 100644 --- a/Makefile +++ b/Makefile @@ -806,7 +806,7 @@ all: vmlinux CFLAGS_GCOV := -fprofile-arcs -ftest-coverage ifdef CONFIG_CC_IS_GCC -CFLAGS_GCOV += -fno-tree-loop-im +CFLAGS_GCOV += -fno-tree-loop-im -fprofile-update=atomic endif export CFLAGS_GCOV -- 2.43.5 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] gcov: use atomic counter updates to fix concurrent access crashes 2026-04-02 14:18 ` [PATCH] gcov: use atomic counter updates " Konstantin Khorenko @ 2026-04-06 19:37 ` Nathan Chancellor 2026-04-09 8:11 ` Peter Oberparleiter 0 siblings, 1 reply; 4+ messages in thread From: Nathan Chancellor @ 2026-04-06 19:37 UTC (permalink / raw) To: Konstantin Khorenko Cc: Peter Oberparleiter, Mikhail Zaslonko, Nicolas Schier, Masahiro Yamada, Thomas Weißschuh, Arnd Bergmann, Steffen Klassert, Herbert Xu, linux-kbuild, linux-kernel, netdev, Pavel Tikhomirov, Vasileios Almpanis, Jakub Kicinski On Thu, Apr 02, 2026 at 05:18:31PM +0300, Konstantin Khorenko wrote: > GCC's GCOV instrumentation can merge global branch counters with loop > induction variables as an optimization. In inflate_fast(), the inner > copy loops get transformed so that the GCOV counter value is loaded > multiple times to compute the loop base address, start index, and end > bound. Since GCOV counters are global (not per-CPU), concurrent > execution on different CPUs causes the counter to change between loads, > producing inconsistent values and out-of-bounds memory writes. > > The crash manifests during IPComp (IP Payload Compression) processing > when inflate_fast() runs concurrently on multiple CPUs: > > 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 > > At the crash point, the compiler generated three loads from the same > global GCOV counter (__gcov0.inflate_fast+216) to compute base, start, > and end for an indexed loop. Another CPU modified the counter between > loads, making the values inconsistent — the write went 3.4 MB past a > 65 KB buffer. > > Add -fprofile-update=atomic to CFLAGS_GCOV at the global level in the > top-level Makefile. This tells GCC that GCOV counters may be > concurrently accessed, causing counter updates to use atomic > instructions (lock addq) instead of plain load/store. This prevents > the compiler from merging counters with loop induction variables. > > Applying this globally rather than per-subsystem not only addresses the > observed crash in zlib but makes GCOV coverage data more consistent > overall, preventing similar issues in any kernel code path that may > execute concurrently. > > Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> > Tested-by: Peter Oberparleiter <oberpar@linux.ibm.com> > Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> While this is obviously a fix, what are the chances of regressions from this change? As this should only impact GCOV, this could go via whatever tree carries GCOV patches. If Kbuild is to take this change, my vote would be to defer it to 7.2 at this point in the development cycle so that it can have most of a cycle to sit in -next. > --- > Makefile | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/Makefile b/Makefile > index 6b1d9fb1a6b4..a55ad668d6ba 100644 > --- a/Makefile > +++ b/Makefile > @@ -806,7 +806,7 @@ all: vmlinux > > CFLAGS_GCOV := -fprofile-arcs -ftest-coverage > ifdef CONFIG_CC_IS_GCC > -CFLAGS_GCOV += -fno-tree-loop-im > +CFLAGS_GCOV += -fno-tree-loop-im -fprofile-update=atomic > endif > export CFLAGS_GCOV > > -- > 2.43.5 > ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] gcov: use atomic counter updates to fix concurrent access crashes 2026-04-06 19:37 ` Nathan Chancellor @ 2026-04-09 8:11 ` Peter Oberparleiter 0 siblings, 0 replies; 4+ messages in thread From: Peter Oberparleiter @ 2026-04-09 8:11 UTC (permalink / raw) To: Nathan Chancellor, Konstantin Khorenko, Andrew Morton Cc: Mikhail Zaslonko, Nicolas Schier, Masahiro Yamada, Thomas Weißschuh, Arnd Bergmann, Steffen Klassert, Herbert Xu, linux-kbuild, linux-kernel, netdev, Pavel Tikhomirov, Vasileios Almpanis, Jakub Kicinski On 06.04.2026 21:37, Nathan Chancellor wrote: > On Thu, Apr 02, 2026 at 05:18:31PM +0300, Konstantin Khorenko wrote: >> GCC's GCOV instrumentation can merge global branch counters with loop >> induction variables as an optimization. In inflate_fast(), the inner >> copy loops get transformed so that the GCOV counter value is loaded >> multiple times to compute the loop base address, start index, and end >> bound. Since GCOV counters are global (not per-CPU), concurrent >> execution on different CPUs causes the counter to change between loads, >> producing inconsistent values and out-of-bounds memory writes. >> >> The crash manifests during IPComp (IP Payload Compression) processing >> when inflate_fast() runs concurrently on multiple CPUs: >> >> 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 >> >> At the crash point, the compiler generated three loads from the same >> global GCOV counter (__gcov0.inflate_fast+216) to compute base, start, >> and end for an indexed loop. Another CPU modified the counter between >> loads, making the values inconsistent — the write went 3.4 MB past a >> 65 KB buffer. >> >> Add -fprofile-update=atomic to CFLAGS_GCOV at the global level in the >> top-level Makefile. This tells GCC that GCOV counters may be >> concurrently accessed, causing counter updates to use atomic >> instructions (lock addq) instead of plain load/store. This prevents >> the compiler from merging counters with loop induction variables. >> >> Applying this globally rather than per-subsystem not only addresses the >> observed crash in zlib but makes GCOV coverage data more consistent >> overall, preventing similar issues in any kernel code path that may >> execute concurrently. >> >> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> >> Tested-by: Peter Oberparleiter <oberpar@linux.ibm.com> >> Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> > > While this is obviously a fix, what are the chances of regressions from > this change? As this should only impact GCOV, this could go via whatever > tree carries GCOV patches. If Kbuild is to take this change, my vote > would be to defer it to 7.2 at this point in the development cycle so > that it can have most of a cycle to sit in -next. Adding Andrew since he typically integrates GCOV patches via his tree, and for input on how to handle this patch. To summarize the situation, this patch: - is only effective with GCC + GCOV profiling enabled - fixes a run-time crash - improves overall GCOV coverage data consistency - triggers a number of build errors due to side-effects on GCC constant folding and therefore depends on the associated series [1] that fixes these build-errors - has a non-zero chance to trigger additional build-time errors, e.g. in similar macros guarded by arch/config symbols not covered by current testing Given the last point, I agree with Nathan that this patch would benefit from additional test coverage to minimize regression risks, e.g. via a cycle in -next. [1] https://lore.kernel.org/lkml/20260402140558.1437002-1-khorenko@virtuozzo.com/ >> --- >> Makefile | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/Makefile b/Makefile >> index 6b1d9fb1a6b4..a55ad668d6ba 100644 >> --- a/Makefile >> +++ b/Makefile >> @@ -806,7 +806,7 @@ all: vmlinux >> >> CFLAGS_GCOV := -fprofile-arcs -ftest-coverage >> ifdef CONFIG_CC_IS_GCC >> -CFLAGS_GCOV += -fno-tree-loop-im >> +CFLAGS_GCOV += -fno-tree-loop-im -fprofile-update=atomic >> endif >> export CFLAGS_GCOV >> >> -- >> 2.43.5 >> -- Peter Oberparleiter Linux on IBM Z Development - IBM Germany R&D ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-04-09 8:12 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-02 14:18 [PATCH 0/1] gcov: add -fprofile-update=atomic to fix concurrent access crashes Konstantin Khorenko 2026-04-02 14:18 ` [PATCH] gcov: use atomic counter updates " Konstantin Khorenko 2026-04-06 19:37 ` Nathan Chancellor 2026-04-09 8:11 ` Peter Oberparleiter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox