* [PATCH 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV
@ 2026-04-02 14:05 Konstantin Khorenko
2026-04-02 14:05 ` [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Konstantin Khorenko @ 2026-04-02 14:05 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann,
Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel,
Konstantin Khorenko, Pavel Tikhomirov, Vasileios Almpanis
This mini-series fixes build failures in net/core/skbuff.c when the
kernel is built with CONFIG_GCOV_PROFILE_ALL=y.
This is part of a larger effort to add -fprofile-update=atomic to
global CFLAGS_GCOV (posted earlier as a combined series):
https://lore.kernel.org/lkml/20260401142020.1434243-1-khorenko@virtuozzo.com/T/#t
That combined series was split per subsystem as requested by Jakub.
The companion patches are:
- iommu: disable GCOV for iommu_amdv1.o (sent to iommu maintainers)
- gcov: add -fprofile-update=atomic globally (sent to gcov/kbuild
maintainers, depends on this series and the iommu patch)
Patch 1/2 fixes a pre-existing build failure with CONFIG_GCOV_PROFILE_ALL:
GCOV counters prevent GCC from constant-folding the skb_ext_total_length()
loop. This is v3 of a previously posted standalone fix:
https://lore.kernel.org/lkml/20260331165125.959833-1-khorenko@virtuozzo.com/T/#t
Patch 2/2 is an additional fix needed when -fprofile-update=atomic is
added to CFLAGS_GCOV: __no_profile on the __always_inline function alone
is insufficient because after inlining, the code resides in the caller's
profiled body. The caller needs __no_profile as well.
Konstantin Khorenko (2):
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
net/core/skbuff.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--
2.43.5
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL 2026-04-02 14:05 [PATCH 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko @ 2026-04-02 14:05 ` Konstantin Khorenko 2026-04-02 14:09 ` Vasileios Almpanis 2026-04-07 7:55 ` Paolo Abeni 2026-04-02 14:05 ` [PATCH 2/2] net: add __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2 siblings, 2 replies; 12+ messages in thread From: Konstantin Khorenko @ 2026-04-02 14:05 UTC (permalink / raw) To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Konstantin Khorenko, Pavel Tikhomirov, Vasileios Almpanis When CONFIG_GCOV_PROFILE_ALL=y is enabled, the kernel fails to build: In file included from <command-line>: In function 'skb_extensions_init', inlined from 'skb_init' at net/core/skbuff.c:5214:2: ././include/linux/compiler_types.h:706:45: error: call to '__compiletime_assert_1490' declared with attribute error: BUILD_BUG_ON failed: skb_ext_total_length() > 255 CONFIG_GCOV_PROFILE_ALL adds -fprofile-arcs -ftest-coverage -fno-tree-loop-im to CFLAGS globally. GCC inserts branch profiling counters into the skb_ext_total_length() loop and, combined with -fno-tree-loop-im (which disables loop invariant motion), cannot constant-fold the result. BUILD_BUG_ON requires a compile-time constant and fails. The issue manifests in kernels with 5+ SKB extension types enabled (e.g., after addition of SKB_EXT_CAN, SKB_EXT_PSP). With 4 extensions GCC can still unroll and fold the loop despite GCOV instrumentation; with 5+ it gives up. Mark skb_ext_total_length() with __no_profile to prevent GCOV from inserting counters into this function. Without counters the loop is "clean" and GCC can constant-fold it even with -fno-tree-loop-im active. This allows BUILD_BUG_ON to work correctly while keeping GCOV profiling for the rest of the kernel. This also removes the CONFIG_KCOV_INSTRUMENT_ALL preprocessor guard introduced by d6e5794b06c0, as __no_profile handles both GCOV and KCOV instrumentation at the root cause level rather than just disabling the check. Fixes: 5d21d0a65b57 ("net: generalize calculation of skb extensions length") Fixes: d6e5794b06c0 ("net: avoid build bug in skb extension length calculation") Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> Reviewed-by: Thomas Weißschuh <linux@weissschuh.net> --- net/core/skbuff.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 0e217041958a..47c7f0ab6e84 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5145,7 +5145,7 @@ static const u8 skb_ext_type_len[] = { #endif }; -static __always_inline unsigned int skb_ext_total_length(void) +static __always_inline __no_profile unsigned int skb_ext_total_length(void) { unsigned int l = SKB_EXT_CHUNKSIZEOF(struct skb_ext); int i; @@ -5159,9 +5159,7 @@ static __always_inline unsigned int skb_ext_total_length(void) static void skb_extensions_init(void) { BUILD_BUG_ON(SKB_EXT_NUM > 8); -#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL) BUILD_BUG_ON(skb_ext_total_length() > 255); -#endif skbuff_ext_cache = kmem_cache_create("skbuff_ext_cache", SKB_EXT_ALIGN_VALUE * skb_ext_total_length(), -- 2.43.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL 2026-04-02 14:05 ` [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko @ 2026-04-02 14:09 ` Vasileios Almpanis 2026-04-07 7:55 ` Paolo Abeni 1 sibling, 0 replies; 12+ messages in thread From: Vasileios Almpanis @ 2026-04-02 14:09 UTC (permalink / raw) To: Konstantin Khorenko, David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Pavel Tikhomirov Reviewed-by: Vasileios Almpanis <vasileios.almpanis@virtuozzo.com> On 4/2/26 4:05 PM, Konstantin Khorenko wrote: > When CONFIG_GCOV_PROFILE_ALL=y is enabled, the kernel fails to build: > > In file included from <command-line>: > In function 'skb_extensions_init', > inlined from 'skb_init' at net/core/skbuff.c:5214:2: > ././include/linux/compiler_types.h:706:45: error: call to > '__compiletime_assert_1490' declared with attribute error: > BUILD_BUG_ON failed: skb_ext_total_length() > 255 > > CONFIG_GCOV_PROFILE_ALL adds -fprofile-arcs -ftest-coverage > -fno-tree-loop-im to CFLAGS globally. GCC inserts branch profiling > counters into the skb_ext_total_length() loop and, combined with > -fno-tree-loop-im (which disables loop invariant motion), cannot > constant-fold the result. > BUILD_BUG_ON requires a compile-time constant and fails. > > The issue manifests in kernels with 5+ SKB extension types enabled > (e.g., after addition of SKB_EXT_CAN, SKB_EXT_PSP). With 4 extensions > GCC can still unroll and fold the loop despite GCOV instrumentation; > with 5+ it gives up. > > Mark skb_ext_total_length() with __no_profile to prevent GCOV from > inserting counters into this function. Without counters the loop is > "clean" and GCC can constant-fold it even with -fno-tree-loop-im active. > This allows BUILD_BUG_ON to work correctly while keeping GCOV profiling > for the rest of the kernel. > > This also removes the CONFIG_KCOV_INSTRUMENT_ALL preprocessor guard > introduced by d6e5794b06c0, as __no_profile handles both GCOV and KCOV > instrumentation at the root cause level rather than just disabling the > check. > > Fixes: 5d21d0a65b57 ("net: generalize calculation of skb extensions length") > Fixes: d6e5794b06c0 ("net: avoid build bug in skb extension length calculation") > > Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> > Reviewed-by: Thomas Weißschuh <linux@weissschuh.net> > --- > net/core/skbuff.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/net/core/skbuff.c b/net/core/skbuff.c > index 0e217041958a..47c7f0ab6e84 100644 > --- a/net/core/skbuff.c > +++ b/net/core/skbuff.c > @@ -5145,7 +5145,7 @@ static const u8 skb_ext_type_len[] = { > #endif > }; > > -static __always_inline unsigned int skb_ext_total_length(void) > +static __always_inline __no_profile unsigned int skb_ext_total_length(void) > { > unsigned int l = SKB_EXT_CHUNKSIZEOF(struct skb_ext); > int i; > @@ -5159,9 +5159,7 @@ static __always_inline unsigned int skb_ext_total_length(void) > static void skb_extensions_init(void) > { > BUILD_BUG_ON(SKB_EXT_NUM > 8); > -#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL) > BUILD_BUG_ON(skb_ext_total_length() > 255); > -#endif > > skbuff_ext_cache = kmem_cache_create("skbuff_ext_cache", > SKB_EXT_ALIGN_VALUE * skb_ext_total_length(), ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL 2026-04-02 14:05 ` [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko 2026-04-02 14:09 ` Vasileios Almpanis @ 2026-04-07 7:55 ` Paolo Abeni 2026-04-09 21:43 ` Konstantin Khorenko 1 sibling, 1 reply; 12+ messages in thread From: Paolo Abeni @ 2026-04-07 7:55 UTC (permalink / raw) To: Konstantin Khorenko, David S . Miller, Eric Dumazet, Jakub Kicinski Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Pavel Tikhomirov, Vasileios Almpanis On 4/2/26 4:05 PM, Konstantin Khorenko wrote: > When CONFIG_GCOV_PROFILE_ALL=y is enabled, the kernel fails to build: > > In file included from <command-line>: > In function 'skb_extensions_init', > inlined from 'skb_init' at net/core/skbuff.c:5214:2: > ././include/linux/compiler_types.h:706:45: error: call to > '__compiletime_assert_1490' declared with attribute error: > BUILD_BUG_ON failed: skb_ext_total_length() > 255 > > CONFIG_GCOV_PROFILE_ALL adds -fprofile-arcs -ftest-coverage > -fno-tree-loop-im to CFLAGS globally. GCC inserts branch profiling > counters into the skb_ext_total_length() loop and, combined with > -fno-tree-loop-im (which disables loop invariant motion), cannot > constant-fold the result. > BUILD_BUG_ON requires a compile-time constant and fails. > > The issue manifests in kernels with 5+ SKB extension types enabled > (e.g., after addition of SKB_EXT_CAN, SKB_EXT_PSP). With 4 extensions > GCC can still unroll and fold the loop despite GCOV instrumentation; > with 5+ it gives up. > > Mark skb_ext_total_length() with __no_profile to prevent GCOV from > inserting counters into this function. Without counters the loop is > "clean" and GCC can constant-fold it even with -fno-tree-loop-im active. > This allows BUILD_BUG_ON to work correctly while keeping GCOV profiling > for the rest of the kernel. > > This also removes the CONFIG_KCOV_INSTRUMENT_ALL preprocessor guard > introduced by d6e5794b06c0, as __no_profile handles both GCOV and KCOV > instrumentation at the root cause level rather than just disabling the > check. > > Fixes: 5d21d0a65b57 ("net: generalize calculation of skb extensions length") > Fixes: d6e5794b06c0 ("net: avoid build bug in skb extension length calculation") > > Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> No empty lines in the tags area. Also given the commit description, isn't the introduction of the 5th skb extension a better fixes tag? > Reviewed-by: Thomas Weißschuh <linux@weissschuh.net> > --- > net/core/skbuff.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > > diff --git a/net/core/skbuff.c b/net/core/skbuff.c > index 0e217041958a..47c7f0ab6e84 100644 > --- a/net/core/skbuff.c > +++ b/net/core/skbuff.c > @@ -5145,7 +5145,7 @@ static const u8 skb_ext_type_len[] = { > #endif > }; > > -static __always_inline unsigned int skb_ext_total_length(void) > +static __always_inline __no_profile unsigned int skb_ext_total_length(void) > { > unsigned int l = SKB_EXT_CHUNKSIZEOF(struct skb_ext); > int i; > @@ -5159,9 +5159,7 @@ static __always_inline unsigned int skb_ext_total_length(void) > static void skb_extensions_init(void) > { > BUILD_BUG_ON(SKB_EXT_NUM > 8); > -#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL) > BUILD_BUG_ON(skb_ext_total_length() > 255); > -#endif Sashiko notes that there could be still build breakage: https://sashiko.dev/#/patchset/20260402140558.1437002-1-khorenko%40virtuozzo.com Could you please double check the above? I think a 'noinline' in skb_extensions_init() would address any complains on patch 2/2 /P > > skbuff_ext_cache = kmem_cache_create("skbuff_ext_cache", > SKB_EXT_ALIGN_VALUE * skb_ext_total_length(), ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL 2026-04-07 7:55 ` Paolo Abeni @ 2026-04-09 21:43 ` Konstantin Khorenko 0 siblings, 0 replies; 12+ messages in thread From: Konstantin Khorenko @ 2026-04-09 21:43 UTC (permalink / raw) To: Paolo Abeni, David S . Miller, Eric Dumazet, Jakub Kicinski Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Pavel Tikhomirov, Vasileios Almpanis On 4/7/26 09:55, Paolo Abeni wrote: > On 4/2/26 4:05 PM, Konstantin Khorenko wrote: ... >> >> Fixes: 5d21d0a65b57 ("net: generalize calculation of skb extensions length") >> Fixes: d6e5794b06c0 ("net: avoid build bug in skb extension length calculation") >> >> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> > > No empty lines in the tags area. Sure, will fix. > Also given the commit description, isn't the introduction of the 5th skb > extension a better fixes tag? Well, if we did not have 5d21d0a65b57 ("net: generalize calculation of skb extensions length"), we won't have a problem even after 5th skb extension. On the other hand, yes, the defect reveals itself only after the appearance of the 5th skb extension, so we can also treat it guilty. i will change the Fixes: tag. >> Reviewed-by: Thomas Weißschuh <linux@weissschuh.net> >> --- >> net/core/skbuff.c | 4 +--- >> 1 file changed, 1 insertion(+), 3 deletions(-) >> >> diff --git a/net/core/skbuff.c b/net/core/skbuff.c >> index 0e217041958a..47c7f0ab6e84 100644 >> --- a/net/core/skbuff.c >> +++ b/net/core/skbuff.c >> @@ -5145,7 +5145,7 @@ static const u8 skb_ext_type_len[] = { >> #endif >> }; >> >> -static __always_inline unsigned int skb_ext_total_length(void) >> +static __always_inline __no_profile unsigned int skb_ext_total_length(void) >> { >> unsigned int l = SKB_EXT_CHUNKSIZEOF(struct skb_ext); >> int i; >> @@ -5159,9 +5159,7 @@ static __always_inline unsigned int skb_ext_total_length(void) >> static void skb_extensions_init(void) >> { >> BUILD_BUG_ON(SKB_EXT_NUM > 8); >> -#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL) >> BUILD_BUG_ON(skb_ext_total_length() > 255); >> -#endif > > Sashiko notes that there could be still build breakage: > > https://sashiko.dev/#/patchset/20260402140558.1437002-1-khorenko%40virtuozzo.com > > Could you please double check the above? Sashiko is great! The concern about KCOV is valid in theory but doesn't apply in practice. Here's why: __no_profile (__no_profile_instrument_function__) indeed only prevents GCOV profiling counters (-fprofile-arcs) from being inserted. It has no effect on KCOV instrumentation (-fsanitize-coverage=trace-pc), which would require __no_sanitize_coverage instead. However, KCOV instrumentation does not break constant folding in the first place. I verified this with a standalone test: a __always_inline function with a loop over a const array (mimicking skb_ext_total_length()), compiled with different instrumentation flags: * No instrumentation: BUILD_BUG_ON passes (constant folded) * GCOV (-fprofile-arcs -ftest-coverage -fno-tree-loop-im): BUILD_BUG_ON fails * KCOV (-fsanitize-coverage=trace-pc): BUILD_BUG_ON passes (constant folded) * GCOV + atomic (-fprofile-arcs -ftest-coverage -fno-tree-loop-im -fprofile-update=atomic): BUILD_BUG_ON fails The difference is in how GCC instruments code. GCOV inserts global counter increments inside the loop body. Combined with -fno-tree-loop-im, these counter operations prevent GCC from proving the loop result is a compile-time constant. KCOV only inserts __sanitizer_cov_trace_pc() callbacks at basic block entries - these are opaque function calls that don't participate in value computation, so GCC can still see the loop iterates over a const array and fold it. > I think a 'noinline' in skb_extensions_init() would address any > complains on patch 2/2 Yes, will add "noinline" to be on a safe side. -- Konstantin Khorenko ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/2] net: add __no_profile to skb_extensions_init() for GCOV compatibility 2026-04-02 14:05 [PATCH 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2026-04-02 14:05 ` [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko @ 2026-04-02 14:05 ` Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2 siblings, 0 replies; 12+ messages in thread From: Konstantin Khorenko @ 2026-04-02 14:05 UTC (permalink / raw) To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Konstantin Khorenko, Pavel Tikhomirov, Vasileios Almpanis With -fprofile-update=atomic in global CFLAGS_GCOV, GCC still cannot constant-fold the skb_ext_total_length() loop when it is inlined into a profiled caller. The existing __no_profile on skb_ext_total_length() itself is insufficient because after __always_inline expansion the code resides in the caller's body, which still carries GCOV instrumentation. Mark skb_extensions_init() with __no_profile so the BUILD_BUG_ON checks can be evaluated at compile time. Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> --- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 47c7f0ab6e84..99704d6832e2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5156,7 +5156,7 @@ static __always_inline __no_profile unsigned int skb_ext_total_length(void) return l; } -static void skb_extensions_init(void) +static void __no_profile skb_extensions_init(void) { BUILD_BUG_ON(SKB_EXT_NUM > 8); BUILD_BUG_ON(skb_ext_total_length() > 255); -- 2.43.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV 2026-04-02 14:05 [PATCH 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2026-04-02 14:05 ` [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko 2026-04-02 14:05 ` [PATCH 2/2] net: add __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko @ 2026-04-09 21:47 ` Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko ` (2 more replies) 2 siblings, 3 replies; 12+ messages in thread From: Konstantin Khorenko @ 2026-04-09 21:47 UTC (permalink / raw) To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Pavel Tikhomirov, Vasileios Almpanis, Konstantin Khorenko This mini-series fixes build failures in net/core/skbuff.c when the kernel is built with CONFIG_GCOV_PROFILE_ALL=y. This is part of a larger effort to add -fprofile-update=atomic to global CFLAGS_GCOV (posted earlier as a combined series) [1]. The companion patch: - gcov: add -fprofile-update=atomic globally (sent to gcov/kbuild maintainers, depends on this series) [2] There was another companion patch here, but i appeared to be already applied recently: 8b72aa5704c7 ("iommupt/amdv1: mark amdv1pt_install_leaf_entry as __always_inline"). Patch 1/2 fixes a pre-existing build failure with CONFIG_GCOV_PROFILE_ALL: GCOV counters prevent GCC from constant-folding the skb_ext_total_length() loop. It also removes the CONFIG_KCOV_INSTRUMENT_ALL preprocessor guard from d6e5794b06c0: that guard was a precaution in case KCOV instrumentation also prevented constant folding, but KCOV's -fsanitize-coverage=trace-pc does not interfere with GCC's constant folding (verified experimentally with GCC 14.2 and GCC 16.0.1), so the guard is unnecessary. Patch 2/2 is an additional fix needed when -fprofile-update=atomic is added to CFLAGS_GCOV: __no_profile on the __always_inline function alone is insufficient because after inlining, the code resides in the caller's profiled body. The caller (skb_extensions_init) needs __no_profile and noinline to prevent re-exposure to GCOV instrumentation. Changes v1 -> v2: - Patch 1/2: expanded the commit message to explain why removing the CONFIG_KCOV_INSTRUMENT_ALL guard is safe (KCOV's -fsanitize-coverage=trace-pc does not inhibit constant folding, unlike GCOV's -fprofile-arcs + -fno-tree-loop-im). Changed Fixes tag to point at the commit that introduced the 5th SKB extension type which triggered the failure. Removed empty lines in tags area. - Patch 2/2: added noinline to skb_extensions_init() to prevent the compiler from inlining it into skb_init(), which would re-expose the function body to GCOV instrumentation. v1: https://lore.kernel.org/lkml/20260402140558.1437002-1-khorenko@virtuozzo.com/T/#t [1] https://lore.kernel.org/lkml/20260401142020.1434243-1-khorenko@virtuozzo.com/T/#t [2] https://lore.kernel.org/lkml/20260402141831.1437357-1-khorenko@virtuozzo.com/T/#t Tested with: - GCC 14.2.1, CONFIG_GCOV_PROFILE_ALL=y - GCC 14.2.1, CONFIG_KCOV_INSTRUMENT_ALL=y (GCOV disabled) - GCC 16.0.1 20260327 (experimental), CONFIG_GCOV_PROFILE_ALL=y Konstantin Khorenko (2): net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL net: add noinline __no_profile to skb_extensions_init() for GCOV compatibility net/core/skbuff.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) -- 2.43.5 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL 2026-04-09 21:47 ` [PATCH v2 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko @ 2026-04-09 21:47 ` Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 2/2] net: add noinline __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko 2026-04-10 16:21 ` [PATCH v3 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2 siblings, 0 replies; 12+ messages in thread From: Konstantin Khorenko @ 2026-04-09 21:47 UTC (permalink / raw) To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Pavel Tikhomirov, Vasileios Almpanis, Konstantin Khorenko When CONFIG_GCOV_PROFILE_ALL=y is enabled, the kernel fails to build: In file included from <command-line>: In function 'skb_extensions_init', inlined from 'skb_init' at net/core/skbuff.c:5214:2: ././include/linux/compiler_types.h:706:45: error: call to '__compiletime_assert_1490' declared with attribute error: BUILD_BUG_ON failed: skb_ext_total_length() > 255 CONFIG_GCOV_PROFILE_ALL adds -fprofile-arcs -ftest-coverage -fno-tree-loop-im to CFLAGS globally. GCC inserts branch profiling counters into the skb_ext_total_length() loop and, combined with -fno-tree-loop-im (which disables loop invariant motion), cannot constant-fold the result. BUILD_BUG_ON requires a compile-time constant and fails. The issue manifests in kernels with 5+ SKB extension types enabled (e.g., after addition of SKB_EXT_CAN, SKB_EXT_PSP). With 4 extensions GCC can still unroll and fold the loop despite GCOV instrumentation; with 5+ it gives up. Mark skb_ext_total_length() with __no_profile to prevent GCOV from inserting counters into this function. Without counters the loop is "clean" and GCC can constant-fold it even with -fno-tree-loop-im active. This allows BUILD_BUG_ON to work correctly while keeping GCOV profiling for the rest of the kernel. This also removes the CONFIG_KCOV_INSTRUMENT_ALL preprocessor guard introduced by d6e5794b06c0. That guard was added as a precaution because KCOV instrumentation was also suspected of inhibiting constant folding. However, KCOV uses -fsanitize-coverage=trace-pc, which inserts lightweight trace callbacks that do not interfere with GCC's constant folding or loop optimization passes. Only GCOV's -fprofile-arcs combined with -fno-tree-loop-im actually prevents the compiler from evaluating the loop at compile time. The guard is therefore unnecessary and can be safely removed. Fixes: 96ea3a1e2d31 ("can: add CAN skb extension infrastructure") Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> Reviewed-by: Thomas Weissschuh <linux@weissschuh.net> --- net/core/skbuff.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 43ee86dcf2ea..59fb4b2bb821 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5142,7 +5142,7 @@ static const u8 skb_ext_type_len[] = { #endif }; -static __always_inline unsigned int skb_ext_total_length(void) +static __always_inline __no_profile unsigned int skb_ext_total_length(void) { unsigned int l = SKB_EXT_CHUNKSIZEOF(struct skb_ext); int i; @@ -5156,9 +5156,7 @@ static __always_inline unsigned int skb_ext_total_length(void) static void skb_extensions_init(void) { BUILD_BUG_ON(SKB_EXT_NUM > 8); -#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL) BUILD_BUG_ON(skb_ext_total_length() > 255); -#endif skbuff_ext_cache = kmem_cache_create("skbuff_ext_cache", SKB_EXT_ALIGN_VALUE * skb_ext_total_length(), -- 2.43.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/2] net: add noinline __no_profile to skb_extensions_init() for GCOV compatibility 2026-04-09 21:47 ` [PATCH v2 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko @ 2026-04-09 21:47 ` Konstantin Khorenko 2026-04-10 16:21 ` [PATCH v3 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2 siblings, 0 replies; 12+ messages in thread From: Konstantin Khorenko @ 2026-04-09 21:47 UTC (permalink / raw) To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Pavel Tikhomirov, Vasileios Almpanis, Konstantin Khorenko With -fprofile-update=atomic in global CFLAGS_GCOV, GCC still cannot constant-fold the skb_ext_total_length() loop when it is inlined into a profiled caller. The existing __no_profile on skb_ext_total_length() itself is insufficient because after __always_inline expansion the code resides in the caller's body, which still carries GCOV instrumentation. Mark skb_extensions_init() with __no_profile so the BUILD_BUG_ON checks can be evaluated at compile time. Also mark it noinline to prevent the compiler from inlining it into skb_init() (which lacks __no_profile), which would re-expose the function body to GCOV instrumentation. Build-tested with both CONFIG_GCOV_PROFILE_ALL=y and CONFIG_KCOV_INSTRUMENT_ALL=y. Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> --- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 59fb4b2bb821..8d75e352e3b1 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5153,7 +5153,7 @@ static __always_inline __no_profile unsigned int skb_ext_total_length(void) return l; } -static void skb_extensions_init(void) +static noinline void __no_profile skb_extensions_init(void) { BUILD_BUG_ON(SKB_EXT_NUM > 8); BUILD_BUG_ON(skb_ext_total_length() > 255); -- 2.43.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV 2026-04-09 21:47 ` [PATCH v2 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 2/2] net: add noinline __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko @ 2026-04-10 16:21 ` Konstantin Khorenko 2026-04-10 16:21 ` [PATCH v3 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko 2026-04-10 16:21 ` [PATCH v3 2/2] net: add noinline __init __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko 2 siblings, 2 replies; 12+ messages in thread From: Konstantin Khorenko @ 2026-04-10 16:21 UTC (permalink / raw) To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Pavel Tikhomirov, Vasileios Almpanis, Konstantin Khorenko This mini-series fixes build failures in net/core/skbuff.c when the kernel is built with CONFIG_GCOV_PROFILE_ALL=y. This is part of a larger effort to add -fprofile-update=atomic to global CFLAGS_GCOV (posted earlier as a combined series): https://lore.kernel.org/lkml/20260401142020.1434243-1-khorenko@virtuozzo.com/T/#t That combined series was split per subsystem as requested by Jakub. The companion patches are: - iommu: use __always_inline for amdv1pt_install_leaf_entry() (sent to iommu maintainers) - gcov: add -fprofile-update=atomic globally (sent to gcov/kbuild maintainers, depends on this series and the iommu patch) Patch 1/2 fixes a pre-existing build failure with CONFIG_GCOV_PROFILE_ALL: GCOV counters prevent GCC from constant-folding the skb_ext_total_length() loop. It also removes the CONFIG_KCOV_INSTRUMENT_ALL preprocessor guard from d6e5794b06c0: that guard was a precaution in case KCOV instrumentation also prevented constant folding, but KCOV's -fsanitize-coverage=trace-pc does not interfere with GCC's constant folding (verified experimentally with GCC 14.2 and GCC 16.0.1), so the guard is unnecessary. Patch 2/2 is an additional fix needed when -fprofile-update=atomic is added to CFLAGS_GCOV: __no_profile on the __always_inline function alone is insufficient because after inlining, the code resides in the caller's profiled body. The caller (skb_extensions_init) needs __no_profile and noinline to prevent re-exposure to GCOV instrumentation. Changes v2 -> v3: - Patch 2/2: added __init since skb_extensions_init() is only called from __init skb_init() - without it noinline would keep the function in permanent .text, wasting memory after boot. Changes v1 -> v2: - Patch 1/2: expanded the commit message to explain why removing the CONFIG_KCOV_INSTRUMENT_ALL guard is safe (KCOV's -fsanitize-coverage=trace-pc does not inhibit constant folding, unlike GCOV's -fprofile-arcs + -fno-tree-loop-im). Changed Fixes tag to point at the commit that introduced the 5th SKB extension type which triggered the failure. Removed empty lines in tags area. - Patch 2/2: added noinline to skb_extensions_init() to prevent the compiler from inlining it into skb_init(), which would re-expose the function body to GCOV instrumentation. v2: https://lore.kernel.org/lkml/20260402140558.1437002-1-khorenko@virtuozzo.com/T/#t v1: https://lore.kernel.org/lkml/20260401142020.1434243-1-khorenko@virtuozzo.com/T/#t Tested with: - GCC 14.2.1, CONFIG_GCOV_PROFILE_ALL=y - GCC 14.2.1, CONFIG_KCOV_INSTRUMENT_ALL=y (GCOV disabled) - GCC 16.0.1 20260327 (experimental), CONFIG_GCOV_PROFILE_ALL=y Konstantin Khorenko (2): net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL net: add noinline __init __no_profile to skb_extensions_init() for GCOV compatibility net/core/skbuff.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) -- 2.43.5 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v3 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL 2026-04-10 16:21 ` [PATCH v3 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko @ 2026-04-10 16:21 ` Konstantin Khorenko 2026-04-10 16:21 ` [PATCH v3 2/2] net: add noinline __init __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko 1 sibling, 0 replies; 12+ messages in thread From: Konstantin Khorenko @ 2026-04-10 16:21 UTC (permalink / raw) To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Pavel Tikhomirov, Vasileios Almpanis, Konstantin Khorenko When CONFIG_GCOV_PROFILE_ALL=y is enabled, the kernel fails to build: In file included from <command-line>: In function 'skb_extensions_init', inlined from 'skb_init' at net/core/skbuff.c:5214:2: ././include/linux/compiler_types.h:706:45: error: call to '__compiletime_assert_1490' declared with attribute error: BUILD_BUG_ON failed: skb_ext_total_length() > 255 CONFIG_GCOV_PROFILE_ALL adds -fprofile-arcs -ftest-coverage -fno-tree-loop-im to CFLAGS globally. GCC inserts branch profiling counters into the skb_ext_total_length() loop and, combined with -fno-tree-loop-im (which disables loop invariant motion), cannot constant-fold the result. BUILD_BUG_ON requires a compile-time constant and fails. The issue manifests in kernels with 5+ SKB extension types enabled (e.g., after addition of SKB_EXT_CAN, SKB_EXT_PSP). With 4 extensions GCC can still unroll and fold the loop despite GCOV instrumentation; with 5+ it gives up. Mark skb_ext_total_length() with __no_profile to prevent GCOV from inserting counters into this function. Without counters the loop is "clean" and GCC can constant-fold it even with -fno-tree-loop-im active. This allows BUILD_BUG_ON to work correctly while keeping GCOV profiling for the rest of the kernel. This also removes the CONFIG_KCOV_INSTRUMENT_ALL preprocessor guard introduced by d6e5794b06c0. That guard was added as a precaution because KCOV instrumentation was also suspected of inhibiting constant folding. However, KCOV uses -fsanitize-coverage=trace-pc, which inserts lightweight trace callbacks that do not interfere with GCC's constant folding or loop optimization passes. Only GCOV's -fprofile-arcs combined with -fno-tree-loop-im actually prevents the compiler from evaluating the loop at compile time. The guard is therefore unnecessary and can be safely removed. Fixes: 96ea3a1e2d31 ("can: add CAN skb extension infrastructure") Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> Reviewed-by: Thomas Weissschuh <linux@weissschuh.net> --- net/core/skbuff.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 43ee86dcf2ea..59fb4b2bb821 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5142,7 +5142,7 @@ static const u8 skb_ext_type_len[] = { #endif }; -static __always_inline unsigned int skb_ext_total_length(void) +static __always_inline __no_profile unsigned int skb_ext_total_length(void) { unsigned int l = SKB_EXT_CHUNKSIZEOF(struct skb_ext); int i; @@ -5156,9 +5156,7 @@ static __always_inline unsigned int skb_ext_total_length(void) static void skb_extensions_init(void) { BUILD_BUG_ON(SKB_EXT_NUM > 8); -#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL) BUILD_BUG_ON(skb_ext_total_length() > 255); -#endif skbuff_ext_cache = kmem_cache_create("skbuff_ext_cache", SKB_EXT_ALIGN_VALUE * skb_ext_total_length(), -- 2.43.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 2/2] net: add noinline __init __no_profile to skb_extensions_init() for GCOV compatibility 2026-04-10 16:21 ` [PATCH v3 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2026-04-10 16:21 ` [PATCH v3 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko @ 2026-04-10 16:21 ` Konstantin Khorenko 1 sibling, 0 replies; 12+ messages in thread From: Konstantin Khorenko @ 2026-04-10 16:21 UTC (permalink / raw) To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni Cc: Simon Horman, Thomas Weißschuh, Arnd Bergmann, Peter Oberparleiter, Mikhail Zaslonko, netdev, linux-kernel, Pavel Tikhomirov, Vasileios Almpanis, Konstantin Khorenko With -fprofile-update=atomic in global CFLAGS_GCOV, GCC still cannot constant-fold the skb_ext_total_length() loop when it is inlined into a profiled caller. The existing __no_profile on skb_ext_total_length() itself is insufficient because after __always_inline expansion the code resides in the caller's body, which still carries GCOV instrumentation. Mark skb_extensions_init() with __no_profile so the BUILD_BUG_ON checks can be evaluated at compile time. Also mark it noinline to prevent the compiler from inlining it into skb_init() (which lacks __no_profile), which would re-expose the function body to GCOV instrumentation. Add __init since skb_extensions_init() is only called from __init skb_init(). Previously it was implicitly inlined into the .init.text section; with noinline it would otherwise remain in permanent .text, wasting memory after boot. Build-tested with both CONFIG_GCOV_PROFILE_ALL=y and CONFIG_KCOV_INSTRUMENT_ALL=y. Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> --- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 59fb4b2bb821..0978f526acf4 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5153,7 +5153,7 @@ static __always_inline __no_profile unsigned int skb_ext_total_length(void) return l; } -static void skb_extensions_init(void) +static noinline void __init __no_profile skb_extensions_init(void) { BUILD_BUG_ON(SKB_EXT_NUM > 8); BUILD_BUG_ON(skb_ext_total_length() > 255); -- 2.43.5 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-04-10 16:22 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-02 14:05 [PATCH 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2026-04-02 14:05 ` [PATCH 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko 2026-04-02 14:09 ` Vasileios Almpanis 2026-04-07 7:55 ` Paolo Abeni 2026-04-09 21:43 ` Konstantin Khorenko 2026-04-02 14:05 ` [PATCH 2/2] net: add __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko 2026-04-09 21:47 ` [PATCH v2 2/2] net: add noinline __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko 2026-04-10 16:21 ` [PATCH v3 0/2] net: fix skb_ext BUILD_BUG_ON failures with GCOV Konstantin Khorenko 2026-04-10 16:21 ` [PATCH v3 1/2] net: fix skb_ext_total_length() BUILD_BUG_ON with CONFIG_GCOV_PROFILE_ALL Konstantin Khorenko 2026-04-10 16:21 ` [PATCH v3 2/2] net: add noinline __init __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox