summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>2017-02-04 18:05:08 +0100
committerDavid S. Miller <davem@davemloft.net>2017-02-06 22:53:13 -0500
commit1214628cb1868254e107230c9052f28ff9899b6a (patch)
treea92be9733044041c71a4b1020f9e6f5d5438d129
parentf7cdee8a79a1cb03fa9ca71b825e72f880b344e1 (diff)
bridge: move write-heavy fdb members in their own cache line
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>
-rw-r--r--net/bridge/br_private.h10
1 files changed, 6 insertions, 4 deletions
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 47fd64bf5022..1cbbf63a5ef7 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -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;
};