diff mbox series

[v4,net-next,2/6] cache: enforce cache groups

Message ID 20231026081959.3477034-3-lixiaoyan@google.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series Analyze and Reorganize core Networking Structs to optimize cacheline consumption | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 15632 this patch: 15632
netdev/cc_maintainers warning 2 maintainers not CCed: catalin.marinas@arm.com akpm@linux-foundation.org
netdev/build_clang success Errors and warnings before: 3928 this patch: 3928
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 17012 this patch: 17012
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 24 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Coco Li Oct. 26, 2023, 8:19 a.m. UTC
Set up build time warnings to safegaurd against future header changes of
organized structs.

Signed-off-by: Coco Li <lixiaoyan@google.com>
Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
---
 include/linux/cache.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Eric Dumazet Oct. 26, 2023, 9:42 a.m. UTC | #1
On Thu, Oct 26, 2023 at 10:20 AM Coco Li <lixiaoyan@google.com> wrote:
>
> Set up build time warnings to safegaurd against future header changes of

safeguard

> organized structs.
>
> Signed-off-by: Coco Li <lixiaoyan@google.com>
> Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
> Acked-by: Daniel Borkmann <daniel@iogearbox.net>

Reviewed-by: Eric Dumazet <edumazet@google.com>

> ---
>  include/linux/cache.h | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/include/linux/cache.h b/include/linux/cache.h
> index 9900d20b76c28..4e547beccd6a5 100644
> --- a/include/linux/cache.h
> +++ b/include/linux/cache.h
> @@ -85,6 +85,24 @@
>  #define cache_line_size()      L1_CACHE_BYTES
>  #endif
>
> +#ifndef __cacheline_group_begin
> +#define __cacheline_group_begin(GROUP) \
> +       __u8 __cacheline_group_begin__##GROUP[0]
> +#endif
> +
> +#ifndef __cacheline_group_end
> +#define __cacheline_group_end(GROUP) \
> +       __u8 __cacheline_group_end__##GROUP[0]
> +#endif
> +
> +#ifndef CACHELINE_ASSERT_GROUP_MEMBER
> +#define CACHELINE_ASSERT_GROUP_MEMBER(TYPE, GROUP, MEMBER) \
> +       BUILD_BUG_ON(!(offsetof(TYPE, MEMBER) >= \
> +                      offsetofend(TYPE, __cacheline_group_begin__##GROUP) && \
> +                      offsetofend(TYPE, MEMBER) <= \
> +                      offsetof(TYPE, __cacheline_group_end__##GROUP)))
> +#endif
> +
>  /*
>   * Helper to add padding within a struct to ensure data fall into separate
>   * cachelines.
> --
> 2.42.0.758.gaed0368e0e-goog
>
Jakub Kicinski Oct. 26, 2023, 2:17 p.m. UTC | #2
On Thu, 26 Oct 2023 08:19:55 +0000 Coco Li wrote:
> Set up build time warnings to safegaurd against future header changes
> of organized structs.

TBH I had some doubts about the value of these asserts, I thought
it was just me but I was talking to Vadim F and he brought up 
the same question.

IIUC these markings will protect us from people moving the members
out of the cache lines. Does that actually happen?

It'd be less typing to assert the _size_ of each group, which protects
from both moving out, and adding stuff haphazardly, which I'd guess is
more common. Perhaps we should do that in addition?
Kuniyuki Iwashima Oct. 26, 2023, 11:39 p.m. UTC | #3
From: Jakub Kicinski <kuba@kernel.org>
Date: Thu, 26 Oct 2023 07:17:01 -0700
> On Thu, 26 Oct 2023 08:19:55 +0000 Coco Li wrote:
> > Set up build time warnings to safegaurd against future header changes
> > of organized structs.
> 
> TBH I had some doubts about the value of these asserts, I thought
> it was just me but I was talking to Vadim F and he brought up 
> the same question.
> 
> IIUC these markings will protect us from people moving the members
> out of the cache lines. Does that actually happen?
> 
> It'd be less typing to assert the _size_ of each group, which protects
> from both moving out, and adding stuff haphazardly, which I'd guess is
> more common. Perhaps we should do that in addition?

Also, we could assert the size of the struct itself and further
add ____cacheline_aligned_in_smp to __cacheline_group_begin() ?

If someone adds/removes a member before __cacheline_group_begin(),
two groups could share the same cacheline.
Coco Li Oct. 26, 2023, 11:50 p.m. UTC | #4
On Thu, Oct 26, 2023 at 4:39 PM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
>
> From: Jakub Kicinski <kuba@kernel.org>
> Date: Thu, 26 Oct 2023 07:17:01 -0700
> > On Thu, 26 Oct 2023 08:19:55 +0000 Coco Li wrote:
> > > Set up build time warnings to safegaurd against future header changes
> > > of organized structs.
> >
> > TBH I had some doubts about the value of these asserts, I thought
> > it was just me but I was talking to Vadim F and he brought up
> > the same question.
> >
> > IIUC these markings will protect us from people moving the members
> > out of the cache lines. Does that actually happen?
> >
> > It'd be less typing to assert the _size_ of each group, which protects
> > from both moving out, and adding stuff haphazardly, which I'd guess is
> > more common. Perhaps we should do that in addition?

SGTM, will add in next patch.

>
> Also, we could assert the size of the struct itself and further
> add ____cacheline_aligned_in_smp to __cacheline_group_begin() ?
>
> If someone adds/removes a member before __cacheline_group_begin(),
> two groups could share the same cacheline.
>
>

I think we shouldn't add
____cacheline_aligned_in_smp/____cacheline_aligned together with
cacheline_group_begin, because especially for read-only cache lines
that are side by side, enforcing them to be in separate cache lines
will result in more total cache lines when we don't care about the
same cache line being shared by multiple cpus.

An example would be tx_read_only group vs rx_read_only group vs
txrx_read_only groups, since there were suggestions that we mark these
cache groups separately.

For cache line separations that we care about (i.e. tcp_sock in tcp.h)
where read and write might potentially be mixed, the
____cacheline_aligned should probably still be only the in header file
only.
Eric Dumazet Oct. 27, 2023, 8:01 a.m. UTC | #5
On Fri, Oct 27, 2023 at 1:39 AM Kuniyuki Iwashima <kuniyu@amazon.com> wrote:
>
> From: Jakub Kicinski <kuba@kernel.org>
> Date: Thu, 26 Oct 2023 07:17:01 -0700
> > On Thu, 26 Oct 2023 08:19:55 +0000 Coco Li wrote:
> > > Set up build time warnings to safegaurd against future header changes
> > > of organized structs.
> >
> > TBH I had some doubts about the value of these asserts, I thought
> > it was just me but I was talking to Vadim F and he brought up
> > the same question.
> >
> > IIUC these markings will protect us from people moving the members
> > out of the cache lines. Does that actually happen?
> >
> > It'd be less typing to assert the _size_ of each group, which protects
> > from both moving out, and adding stuff haphazardly, which I'd guess is
> > more common. Perhaps we should do that in addition?
>
> Also, we could assert the size of the struct itself and further
> add ____cacheline_aligned_in_smp to __cacheline_group_begin() ?

Nope, automatically adding  ____cacheline_aligned_in_smp to each group
is not beneficial.

We ran a lot of experiments and concluded that grouping was the best strategy.

Adding  ____cacheline_aligned_in_smp adds holes and TX + RX traffic (RPC)
would use more cache lines than necessary.


>
> If someone adds/removes a member before __cacheline_group_begin(),
> two groups could share the same cacheline.
>
>
Daniel Borkmann Oct. 27, 2023, 8:21 a.m. UTC | #6
On 10/26/23 4:17 PM, Jakub Kicinski wrote:
> On Thu, 26 Oct 2023 08:19:55 +0000 Coco Li wrote:
>> Set up build time warnings to safegaurd against future header changes
>> of organized structs.
> 
> TBH I had some doubts about the value of these asserts, I thought
> it was just me but I was talking to Vadim F and he brought up
> the same question.
> 
> IIUC these markings will protect us from people moving the members
> out of the cache lines. Does that actually happen?
> 
> It'd be less typing to assert the _size_ of each group, which protects
> from both moving out, and adding stuff haphazardly, which I'd guess is
> more common. Perhaps we should do that in addition?

Size would be good, I also had that in the prototype in [0], I think
blowing up the size is a bigger risk than moving existing members to
somewhere else in the struct, and this way it is kind of a forcing
factor to think deeper when this triggers, and helps in reviews hopefully
as well since it's an explicit change when the size is bumped. Having
this in addition would be nice imo.

Thanks,
Daniel

   [0] https://lore.kernel.org/netdev/50ca7bc1-e5c1-cb79-b2af-e5cd83b54dab@iogearbox.net/
diff mbox series

Patch

diff --git a/include/linux/cache.h b/include/linux/cache.h
index 9900d20b76c28..4e547beccd6a5 100644
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -85,6 +85,24 @@ 
 #define cache_line_size()	L1_CACHE_BYTES
 #endif
 
+#ifndef __cacheline_group_begin
+#define __cacheline_group_begin(GROUP) \
+	__u8 __cacheline_group_begin__##GROUP[0]
+#endif
+
+#ifndef __cacheline_group_end
+#define __cacheline_group_end(GROUP) \
+	__u8 __cacheline_group_end__##GROUP[0]
+#endif
+
+#ifndef CACHELINE_ASSERT_GROUP_MEMBER
+#define CACHELINE_ASSERT_GROUP_MEMBER(TYPE, GROUP, MEMBER) \
+	BUILD_BUG_ON(!(offsetof(TYPE, MEMBER) >= \
+		       offsetofend(TYPE, __cacheline_group_begin__##GROUP) && \
+		       offsetofend(TYPE, MEMBER) <= \
+		       offsetof(TYPE, __cacheline_group_end__##GROUP)))
+#endif
+
 /*
  * Helper to add padding within a struct to ensure data fall into separate
  * cachelines.