diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-13 04:22:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-16 14:13:23 -0400 |
commit | 10da66f7552b3c7966c2f4f1f72009fb0b5539ec (patch) | |
tree | 517c39912a0aea9d4da3c3915c78e832dfbba855 /net/ipv4 | |
parent | 874ffa8f72444d6253d2669fed304875c128f86b (diff) |
fib: avoid false sharing on fib_table_hash
While doing profile analysis, I found fib_hash_table was sometime in a
cache line shared by a possibly often written kernel structure.
(CONFIG_IP_ROUTE_MULTIPATH || !CONFIG_IPV6_MULTIPLE_TABLES)
It's hard to detect because not easily reproductible.
Make sure we allocate a full cache line to keep this shared in all cpus
caches.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/fib_frontend.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 919f2ad19b49..3df057e89640 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -1016,16 +1016,15 @@ static struct notifier_block fib_netdev_notifier = { | |||
1016 | static int __net_init ip_fib_net_init(struct net *net) | 1016 | static int __net_init ip_fib_net_init(struct net *net) |
1017 | { | 1017 | { |
1018 | int err; | 1018 | int err; |
1019 | unsigned int i; | 1019 | size_t size = sizeof(struct hlist_head) * FIB_TABLE_HASHSZ; |
1020 | |||
1021 | /* Avoid false sharing : Use at least a full cache line */ | ||
1022 | size = max_t(size_t, size, L1_CACHE_BYTES); | ||
1020 | 1023 | ||
1021 | net->ipv4.fib_table_hash = kzalloc( | 1024 | net->ipv4.fib_table_hash = kzalloc(size, GFP_KERNEL); |
1022 | sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL); | ||
1023 | if (net->ipv4.fib_table_hash == NULL) | 1025 | if (net->ipv4.fib_table_hash == NULL) |
1024 | return -ENOMEM; | 1026 | return -ENOMEM; |
1025 | 1027 | ||
1026 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) | ||
1027 | INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]); | ||
1028 | |||
1029 | err = fib4_rules_init(net); | 1028 | err = fib4_rules_init(net); |
1030 | if (err < 0) | 1029 | if (err < 0) |
1031 | goto fail; | 1030 | goto fail; |