bridge: fdb: rearrange net_bridge_fdb_entry
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Thu, 27 Aug 2015 21:19:20 +0000 (14:19 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 27 Aug 2015 23:38:52 +0000 (16:38 -0700)
commitb22fbf22f8469d8cacb6fcf5d266426826e1137d
tree6baf442597f98e2bb8d5fb0ee3365163551248f8
parentd3a730971b90dd150e43c924b1b4dec8197fccad
bridge: fdb: rearrange net_bridge_fdb_entry

While looking into fixing the local entries scalability issue I noticed
that the structure is badly arranged because vlan_id would fall in a
second cache line while keeping rcu which is used only when deleting
in the first, so re-arrange the structure and push rcu to the end so we
can get 16 bytes which can be used for other fields (by pushing rcu
fully in the second 64 byte chunk). With this change all the core
necessary information when doing fdb lookups will be available in a
single cache line.

pahole before (note vlan_id):
struct net_bridge_fdb_entry {
struct hlist_node          hlist;                /*     0    16 */
struct net_bridge_port *   dst;                  /*    16     8 */
struct callback_head       rcu;                  /*    24    16 */
long unsigned int          updated;              /*    40     8 */
long unsigned int          used;                 /*    48     8 */
mac_addr                   addr;                 /*    56     6 */
unsigned char              is_local:1;           /*    62: 7  1 */
unsigned char              is_static:1;          /*    62: 6  1 */
unsigned char              added_by_user:1;      /*    62: 5  1 */
unsigned char              added_by_external_learn:1; /*    62: 4  1 */

/* XXX 4 bits hole, try to pack */
/* XXX 1 byte hole, try to pack */

/* --- cacheline 1 boundary (64 bytes) --- */
__u16                      vlan_id;              /*    64     2 */

/* size: 72, cachelines: 2, members: 11 */
/* sum members: 65, holes: 1, sum holes: 1 */
/* bit holes: 1, sum bit holes: 4 bits */
/* padding: 6 */
/* last cacheline: 8 bytes */
}

pahole after (note vlan_id):
struct net_bridge_fdb_entry {
struct hlist_node          hlist;                /*     0    16 */
struct net_bridge_port *   dst;                  /*    16     8 */
long unsigned int          updated;              /*    24     8 */
long unsigned int          used;                 /*    32     8 */
mac_addr                   addr;                 /*    40     6 */
__u16                      vlan_id;              /*    46     2 */
unsigned char              is_local:1;           /*    48: 7  1 */
unsigned char              is_static:1;          /*    48: 6  1 */
unsigned char              added_by_user:1;      /*    48: 5  1 */
unsigned char              added_by_external_learn:1; /*    48: 4  1 */

/* XXX 4 bits hole, try to pack */
/* XXX 7 bytes hole, try to pack */

struct callback_head       rcu;                  /*    56    16 */
/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */

/* size: 72, cachelines: 2, members: 11 */
/* sum members: 65, holes: 1, sum holes: 7 */
/* bit holes: 1, sum bit holes: 4 bits */
/* last cacheline: 8 bytes */
}

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