[Devel] [PATCH vz10 v2] gcov: use atomic counter updates to prevent crash in GCOV-instrumented code

Konstantin Khorenko khorenko at virtuozzo.com
Thu Mar 26 20:20:49 MSK 2026


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.  This tells GCC that GCOV
counters are concurrently accessed, so counter updates use atomic
instructions (lock xadd) instead of plain load/store.  This prevents
the compiler from merging counters with loop induction variables and
also fixes silent counter data loss from concurrent non-atomic
increments.  The flag is available since GCC 4.9.

https://virtuozzo.atlassian.net/browse/VSTOR-127788

Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>

Feature: fix selftests
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Makefile b/Makefile
index 03c79b70daf93..58df11e020d12 100644
--- a/Makefile
+++ b/Makefile
@@ -767,6 +767,7 @@ all: vmlinux
 CFLAGS_GCOV	:= -fprofile-arcs -ftest-coverage
 ifdef CONFIG_CC_IS_GCC
 CFLAGS_GCOV	+= -fno-tree-loop-im
+CFLAGS_GCOV	+= -fprofile-update=atomic
 endif
 export CFLAGS_GCOV
 
-- 
2.43.0



More information about the Devel mailing list