diff options
author | Eric Dumazet <edumazet@google.com> | 2012-07-19 19:02:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-20 13:59:41 -0400 |
commit | 5815d5e7aae3cc9c5e85af83094d4d6498c3f4fc (patch) | |
tree | 68c36b030d6479cdee319db32cdb2ee4d81ee938 /net/ipv4 | |
parent | 67b95bd78f0de85793bf30835913f6ef784a39b6 (diff) |
tcp: use hash_32() in tcp_metrics
Fix a missing roundup_pow_of_two(), since tcpmhash_entries is not
guaranteed to be a power of two.
Uses hash_32() instead of custom hash.
tcpmhash_entries should be an unsigned int.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/tcp_metrics.c | 25 |
1 files changed, 10 insertions, 15 deletions
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 99779ae44f64..992f1bff4fc6 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/slab.h> | 7 | #include <linux/slab.h> |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/tcp.h> | 9 | #include <linux/tcp.h> |
10 | #include <linux/hash.h> | ||
10 | 11 | ||
11 | #include <net/inet_connection_sock.h> | 12 | #include <net/inet_connection_sock.h> |
12 | #include <net/net_namespace.h> | 13 | #include <net/net_namespace.h> |
@@ -228,10 +229,8 @@ static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req, | |||
228 | return NULL; | 229 | return NULL; |
229 | } | 230 | } |
230 | 231 | ||
231 | hash ^= (hash >> 24) ^ (hash >> 16) ^ (hash >> 8); | ||
232 | |||
233 | net = dev_net(dst->dev); | 232 | net = dev_net(dst->dev); |
234 | hash &= net->ipv4.tcp_metrics_hash_mask; | 233 | hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log); |
235 | 234 | ||
236 | for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm; | 235 | for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm; |
237 | tm = rcu_dereference(tm->tcpm_next)) { | 236 | tm = rcu_dereference(tm->tcpm_next)) { |
@@ -265,10 +264,8 @@ static struct tcp_metrics_block *__tcp_get_metrics_tw(struct inet_timewait_sock | |||
265 | return NULL; | 264 | return NULL; |
266 | } | 265 | } |
267 | 266 | ||
268 | hash ^= (hash >> 24) ^ (hash >> 16) ^ (hash >> 8); | ||
269 | |||
270 | net = twsk_net(tw); | 267 | net = twsk_net(tw); |
271 | hash &= net->ipv4.tcp_metrics_hash_mask; | 268 | hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log); |
272 | 269 | ||
273 | for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm; | 270 | for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm; |
274 | tm = rcu_dereference(tm->tcpm_next)) { | 271 | tm = rcu_dereference(tm->tcpm_next)) { |
@@ -302,10 +299,8 @@ static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk, | |||
302 | return NULL; | 299 | return NULL; |
303 | } | 300 | } |
304 | 301 | ||
305 | hash ^= (hash >> 24) ^ (hash >> 16) ^ (hash >> 8); | ||
306 | |||
307 | net = dev_net(dst->dev); | 302 | net = dev_net(dst->dev); |
308 | hash &= net->ipv4.tcp_metrics_hash_mask; | 303 | hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log); |
309 | 304 | ||
310 | tm = __tcp_get_metrics(&addr, net, hash); | 305 | tm = __tcp_get_metrics(&addr, net, hash); |
311 | reclaim = false; | 306 | reclaim = false; |
@@ -694,7 +689,7 @@ void tcp_fastopen_cache_set(struct sock *sk, u16 mss, | |||
694 | rcu_read_unlock(); | 689 | rcu_read_unlock(); |
695 | } | 690 | } |
696 | 691 | ||
697 | static unsigned long tcpmhash_entries; | 692 | static unsigned int tcpmhash_entries; |
698 | static int __init set_tcpmhash_entries(char *str) | 693 | static int __init set_tcpmhash_entries(char *str) |
699 | { | 694 | { |
700 | ssize_t ret; | 695 | ssize_t ret; |
@@ -702,7 +697,7 @@ static int __init set_tcpmhash_entries(char *str) | |||
702 | if (!str) | 697 | if (!str) |
703 | return 0; | 698 | return 0; |
704 | 699 | ||
705 | ret = kstrtoul(str, 0, &tcpmhash_entries); | 700 | ret = kstrtouint(str, 0, &tcpmhash_entries); |
706 | if (ret) | 701 | if (ret) |
707 | return 0; | 702 | return 0; |
708 | 703 | ||
@@ -712,7 +707,8 @@ __setup("tcpmhash_entries=", set_tcpmhash_entries); | |||
712 | 707 | ||
713 | static int __net_init tcp_net_metrics_init(struct net *net) | 708 | static int __net_init tcp_net_metrics_init(struct net *net) |
714 | { | 709 | { |
715 | int slots, size; | 710 | size_t size; |
711 | unsigned int slots; | ||
716 | 712 | ||
717 | slots = tcpmhash_entries; | 713 | slots = tcpmhash_entries; |
718 | if (!slots) { | 714 | if (!slots) { |
@@ -722,14 +718,13 @@ static int __net_init tcp_net_metrics_init(struct net *net) | |||
722 | slots = 8 * 1024; | 718 | slots = 8 * 1024; |
723 | } | 719 | } |
724 | 720 | ||
725 | size = slots * sizeof(struct tcpm_hash_bucket); | 721 | net->ipv4.tcp_metrics_hash_log = order_base_2(slots); |
722 | size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log; | ||
726 | 723 | ||
727 | net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL); | 724 | net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL); |
728 | if (!net->ipv4.tcp_metrics_hash) | 725 | if (!net->ipv4.tcp_metrics_hash) |
729 | return -ENOMEM; | 726 | return -ENOMEM; |
730 | 727 | ||
731 | net->ipv4.tcp_metrics_hash_mask = (slots - 1); | ||
732 | |||
733 | return 0; | 728 | return 0; |
734 | } | 729 | } |
735 | 730 | ||