netns: reorder fields in struct net
authorEric Dumazet <eric.dumazet@gmail.com>
Thu, 14 Oct 2010 05:56:18 +0000 (05:56 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 17 Oct 2010 20:49:14 +0000 (13:49 -0700)
In a network bench, I noticed an unfortunate false sharing between
'loopback_dev' and 'count' fields in "struct net".

'count' is written each time a socket is created or destroyed, while
loopback_dev might be often read in routing code.

Move loopback_dev in a read mostly section of "struct net"

Note: struct netns_xfrm is cache line aligned on SMP.
(It contains a "struct dst_ops")
Move it at the end to avoid holes, and reduce sizeof(struct net) by 128
bytes on ia32.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/net_namespace.h
include/net/netns/xfrm.h

index bd10a7908993fc369de73957751588d933a9bb12..65af9a07cf766b3fe0309149cd46fcc6495aaffb 100644 (file)
@@ -41,6 +41,8 @@ struct net {
                                                 * destroy on demand
                                                 */
 #endif
+       spinlock_t              rules_mod_lock;
+
        struct list_head        list;           /* list of network namespaces */
        struct list_head        cleanup_list;   /* namespaces on death row */
        struct list_head        exit_list;      /* Use only net_mutex */
@@ -52,7 +54,8 @@ struct net {
        struct ctl_table_set    sysctls;
 #endif
 
-       struct net_device       *loopback_dev;          /* The loopback */
+       struct sock             *rtnl;                  /* rtnetlink socket */
+       struct sock             *genl_sock;
 
        struct list_head        dev_base_head;
        struct hlist_head       *dev_name_head;
@@ -60,11 +63,9 @@ struct net {
 
        /* core fib_rules */
        struct list_head        rules_ops;
-       spinlock_t              rules_mod_lock;
 
-       struct sock             *rtnl;                  /* rtnetlink socket */
-       struct sock             *genl_sock;
 
+       struct net_device       *loopback_dev;          /* The loopback */
        struct netns_core       core;
        struct netns_mib        mib;
        struct netns_packet     packet;
@@ -84,13 +85,15 @@ struct net {
        struct sock             *nfnl;
        struct sock             *nfnl_stash;
 #endif
-#ifdef CONFIG_XFRM
-       struct netns_xfrm       xfrm;
-#endif
 #ifdef CONFIG_WEXT_CORE
        struct sk_buff_head     wext_nlevents;
 #endif
        struct net_generic      *gen;
+
+       /* Note : following structs are cache line aligned */
+#ifdef CONFIG_XFRM
+       struct netns_xfrm       xfrm;
+#endif
 };
 
 
index 74f119a2829a2fe8749e28fdccd99822e58e76dc..748f91f87cd573783efcf59a615292a86b2c289e 100644 (file)
@@ -43,10 +43,6 @@ struct netns_xfrm {
        unsigned int            policy_count[XFRM_POLICY_MAX * 2];
        struct work_struct      policy_hash_work;
 
-       struct dst_ops          xfrm4_dst_ops;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-       struct dst_ops          xfrm6_dst_ops;
-#endif
 
        struct sock             *nlsk;
        struct sock             *nlsk_stash;
@@ -58,6 +54,11 @@ struct netns_xfrm {
 #ifdef CONFIG_SYSCTL
        struct ctl_table_header *sysctl_hdr;
 #endif
+
+       struct dst_ops          xfrm4_dst_ops;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+       struct dst_ops          xfrm6_dst_ops;
+#endif
 };
 
 #endif