bridge: move write-heavy fdb members in their own cache line
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Sat, 4 Feb 2017 17:05:08 +0000 (18:05 +0100)
committerDavid S. Miller <davem@davemloft.net>
Tue, 7 Feb 2017 03:53:13 +0000 (22:53 -0500)
Fdb's used and updated fields are written to on every packet forward and
packet receive respectively. Thus if we are receiving packets from a
particular fdb, they'll cause false-sharing with everyone who has looked
it up (even if it didn't match, since mac/vid share cache line!). The
"used" field is even worse since it is updated on every packet forward
to that fdb, thus the standard config where X ports use a single gateway
results in 100% fdb false-sharing. Note that this patch does not prevent
the last scenario, but it makes it better for other bridge participants
which are not using that fdb (and are only doing lookups over it).
The point is with this move we make sure that only communicating parties
get the false-sharing, in a later patch we'll show how to avoid that too.

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/bridge/br_private.h

index 47fd64bf5022e60fc7502ed1fc3e77aac8fb3329..1cbbf63a5ef79f9da29acb1e128ab3e5ec38ce35 100644 (file)
@@ -160,19 +160,21 @@ struct net_bridge_vlan_group {
        u16                             pvid;
 };
 
-struct net_bridge_fdb_entry
-{
+struct net_bridge_fdb_entry {
        struct hlist_node               hlist;
        struct net_bridge_port          *dst;
 
-       unsigned long                   updated;
-       unsigned long                   used;
        mac_addr                        addr;
        __u16                           vlan_id;
        unsigned char                   is_local:1,
                                        is_static:1,
                                        added_by_user:1,
                                        added_by_external_learn:1;
+
+       /* write-heavy members should not affect lookups */
+       unsigned long                   updated ____cacheline_aligned_in_smp;
+       unsigned long                   used;
+
        struct rcu_head                 rcu;
 };