diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-06-16 20:12:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-16 20:12:49 -0400 |
commit | 7f635ab71eef8da012320c0092b662d6af8c1e69 (patch) | |
tree | 21e4af155dbbc1f059b8af0281fdfbc0fb207084 | |
parent | 19c7578fb22b0aef103222cae9b522f03ae489d6 (diff) |
inet: add struct net argument to inet_bhashfn
Binding to some port in many namespaces may create too long
chains in bhash-es, so prepare the hashfn to take struct net
into account.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/inet_hashtables.h | 3 | ||||
-rw-r--r-- | net/ipv4/inet_connection_sock.c | 6 | ||||
-rw-r--r-- | net/ipv4/inet_hashtables.c | 11 | ||||
-rw-r--r-- | net/ipv4/inet_timewait_sock.c | 6 |
4 files changed, 17 insertions, 9 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 735b926a3497..61dd3317089c 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
@@ -201,7 +201,8 @@ extern struct inet_bind_bucket * | |||
201 | extern void inet_bind_bucket_destroy(struct kmem_cache *cachep, | 201 | extern void inet_bind_bucket_destroy(struct kmem_cache *cachep, |
202 | struct inet_bind_bucket *tb); | 202 | struct inet_bind_bucket *tb); |
203 | 203 | ||
204 | static inline int inet_bhashfn(const __u16 lport, const int bhash_size) | 204 | static inline int inet_bhashfn(struct net *net, |
205 | const __u16 lport, const int bhash_size) | ||
205 | { | 206 | { |
206 | return lport & (bhash_size - 1); | 207 | return lport & (bhash_size - 1); |
207 | } | 208 | } |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 045e799d3e1d..4c804b3c287b 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -103,7 +103,8 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) | |||
103 | rover = net_random() % remaining + low; | 103 | rover = net_random() % remaining + low; |
104 | 104 | ||
105 | do { | 105 | do { |
106 | head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)]; | 106 | head = &hashinfo->bhash[inet_bhashfn(net, rover, |
107 | hashinfo->bhash_size)]; | ||
107 | spin_lock(&head->lock); | 108 | spin_lock(&head->lock); |
108 | inet_bind_bucket_for_each(tb, node, &head->chain) | 109 | inet_bind_bucket_for_each(tb, node, &head->chain) |
109 | if (tb->ib_net == net && tb->port == rover) | 110 | if (tb->ib_net == net && tb->port == rover) |
@@ -130,7 +131,8 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) | |||
130 | */ | 131 | */ |
131 | snum = rover; | 132 | snum = rover; |
132 | } else { | 133 | } else { |
133 | head = &hashinfo->bhash[inet_bhashfn(snum, hashinfo->bhash_size)]; | 134 | head = &hashinfo->bhash[inet_bhashfn(net, snum, |
135 | hashinfo->bhash_size)]; | ||
134 | spin_lock(&head->lock); | 136 | spin_lock(&head->lock); |
135 | inet_bind_bucket_for_each(tb, node, &head->chain) | 137 | inet_bind_bucket_for_each(tb, node, &head->chain) |
136 | if (tb->ib_net == net && tb->port == snum) | 138 | if (tb->ib_net == net && tb->port == snum) |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 2023d37b2708..dc1b78de8990 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -70,7 +70,8 @@ void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, | |||
70 | static void __inet_put_port(struct sock *sk) | 70 | static void __inet_put_port(struct sock *sk) |
71 | { | 71 | { |
72 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; | 72 | struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; |
73 | const int bhash = inet_bhashfn(inet_sk(sk)->num, hashinfo->bhash_size); | 73 | const int bhash = inet_bhashfn(sock_net(sk), inet_sk(sk)->num, |
74 | hashinfo->bhash_size); | ||
74 | struct inet_bind_hashbucket *head = &hashinfo->bhash[bhash]; | 75 | struct inet_bind_hashbucket *head = &hashinfo->bhash[bhash]; |
75 | struct inet_bind_bucket *tb; | 76 | struct inet_bind_bucket *tb; |
76 | 77 | ||
@@ -95,7 +96,8 @@ EXPORT_SYMBOL(inet_put_port); | |||
95 | void __inet_inherit_port(struct sock *sk, struct sock *child) | 96 | void __inet_inherit_port(struct sock *sk, struct sock *child) |
96 | { | 97 | { |
97 | struct inet_hashinfo *table = sk->sk_prot->h.hashinfo; | 98 | struct inet_hashinfo *table = sk->sk_prot->h.hashinfo; |
98 | const int bhash = inet_bhashfn(inet_sk(child)->num, table->bhash_size); | 99 | const int bhash = inet_bhashfn(sock_net(sk), inet_sk(child)->num, |
100 | table->bhash_size); | ||
99 | struct inet_bind_hashbucket *head = &table->bhash[bhash]; | 101 | struct inet_bind_hashbucket *head = &table->bhash[bhash]; |
100 | struct inet_bind_bucket *tb; | 102 | struct inet_bind_bucket *tb; |
101 | 103 | ||
@@ -438,7 +440,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, | |||
438 | local_bh_disable(); | 440 | local_bh_disable(); |
439 | for (i = 1; i <= remaining; i++) { | 441 | for (i = 1; i <= remaining; i++) { |
440 | port = low + (i + offset) % remaining; | 442 | port = low + (i + offset) % remaining; |
441 | head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)]; | 443 | head = &hinfo->bhash[inet_bhashfn(net, port, |
444 | hinfo->bhash_size)]; | ||
442 | spin_lock(&head->lock); | 445 | spin_lock(&head->lock); |
443 | 446 | ||
444 | /* Does not bother with rcv_saddr checks, | 447 | /* Does not bother with rcv_saddr checks, |
@@ -493,7 +496,7 @@ ok: | |||
493 | goto out; | 496 | goto out; |
494 | } | 497 | } |
495 | 498 | ||
496 | head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)]; | 499 | head = &hinfo->bhash[inet_bhashfn(net, snum, hinfo->bhash_size)]; |
497 | tb = inet_csk(sk)->icsk_bind_hash; | 500 | tb = inet_csk(sk)->icsk_bind_hash; |
498 | spin_lock_bh(&head->lock); | 501 | spin_lock_bh(&head->lock); |
499 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { | 502 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { |
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index ce16e9ac24c1..06006a5ac8b9 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c | |||
@@ -32,7 +32,8 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw, | |||
32 | write_unlock(lock); | 32 | write_unlock(lock); |
33 | 33 | ||
34 | /* Disassociate with bind bucket. */ | 34 | /* Disassociate with bind bucket. */ |
35 | bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_num, hashinfo->bhash_size)]; | 35 | bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), tw->tw_num, |
36 | hashinfo->bhash_size)]; | ||
36 | spin_lock(&bhead->lock); | 37 | spin_lock(&bhead->lock); |
37 | tb = tw->tw_tb; | 38 | tb = tw->tw_tb; |
38 | __hlist_del(&tw->tw_bind_node); | 39 | __hlist_del(&tw->tw_bind_node); |
@@ -81,7 +82,8 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, | |||
81 | Note, that any socket with inet->num != 0 MUST be bound in | 82 | Note, that any socket with inet->num != 0 MUST be bound in |
82 | binding cache, even if it is closed. | 83 | binding cache, even if it is closed. |
83 | */ | 84 | */ |
84 | bhead = &hashinfo->bhash[inet_bhashfn(inet->num, hashinfo->bhash_size)]; | 85 | bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), inet->num, |
86 | hashinfo->bhash_size)]; | ||
85 | spin_lock(&bhead->lock); | 87 | spin_lock(&bhead->lock); |
86 | tw->tw_tb = icsk->icsk_bind_hash; | 88 | tw->tw_tb = icsk->icsk_bind_hash; |
87 | BUG_TRAP(icsk->icsk_bind_hash); | 89 | BUG_TRAP(icsk->icsk_bind_hash); |