public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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; 9+ 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] 9+ 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
  2026-04-09 21:47   ` [PATCH v2 2/2] net: add noinline __no_profile to skb_extensions_init() for GCOV compatibility Konstantin Khorenko
  2 siblings, 2 replies; 9+ 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] 9+ 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
  1 sibling, 0 replies; 9+ 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] 9+ 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
  1 sibling, 0 replies; 9+ 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] 9+ messages in thread

end of thread, other threads:[~2026-04-09 21:47 UTC | newest]

Thread overview: 9+ 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

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