aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/inet_hashtables.h10
-rw-r--r--net/dccp/proto.c4
-rw-r--r--net/ipv4/inet_diag.c2
-rw-r--r--net/ipv4/inet_hashtables.c2
-rw-r--r--net/ipv4/inet_timewait_sock.c4
-rw-r--r--net/ipv4/tcp.c7
-rw-r--r--net/ipv4/tcp_ipv4.c4
-rw-r--r--net/ipv6/inet6_hashtables.c4
8 files changed, 19 insertions, 18 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 34cc76e3ddb4..d27ee8c0da3f 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -34,12 +34,13 @@
34#include <asm/byteorder.h> 34#include <asm/byteorder.h>
35 35
36/* This is for all connections with a full identity, no wildcards. 36/* This is for all connections with a full identity, no wildcards.
37 * New scheme, half the table is for TIME_WAIT, the other half is 37 * One chain is dedicated to TIME_WAIT sockets.
38 * for the rest. I'll experiment with dynamic table growth later. 38 * I'll experiment with dynamic table growth later.
39 */ 39 */
40struct inet_ehash_bucket { 40struct inet_ehash_bucket {
41 rwlock_t lock; 41 rwlock_t lock;
42 struct hlist_head chain; 42 struct hlist_head chain;
43 struct hlist_head twchain;
43}; 44};
44 45
45/* There are a few simple rules, which allow for local port reuse by 46/* There are a few simple rules, which allow for local port reuse by
@@ -97,8 +98,7 @@ struct inet_hashinfo {
97 * 98 *
98 * TCP_ESTABLISHED <= sk->sk_state < TCP_CLOSE 99 * TCP_ESTABLISHED <= sk->sk_state < TCP_CLOSE
99 * 100 *
100 * First half of the table is for sockets not in TIME_WAIT, second half 101 * TIME_WAIT sockets use a separate chain (twchain).
101 * is for TIME_WAIT sockets only.
102 */ 102 */
103 struct inet_ehash_bucket *ehash; 103 struct inet_ehash_bucket *ehash;
104 104
@@ -369,7 +369,7 @@ static inline struct sock *
369 } 369 }
370 370
371 /* Must check for a TIME_WAIT'er before going to listener hash. */ 371 /* Must check for a TIME_WAIT'er before going to listener hash. */
372 sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) { 372 sk_for_each(sk, node, &head->twchain) {
373 if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) 373 if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
374 goto hit; 374 goto hit;
375 } 375 }
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 63b3fa20e14b..48438565d70f 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1024,7 +1024,6 @@ static int __init dccp_init(void)
1024 do { 1024 do {
1025 dccp_hashinfo.ehash_size = (1UL << ehash_order) * PAGE_SIZE / 1025 dccp_hashinfo.ehash_size = (1UL << ehash_order) * PAGE_SIZE /
1026 sizeof(struct inet_ehash_bucket); 1026 sizeof(struct inet_ehash_bucket);
1027 dccp_hashinfo.ehash_size >>= 1;
1028 while (dccp_hashinfo.ehash_size & 1027 while (dccp_hashinfo.ehash_size &
1029 (dccp_hashinfo.ehash_size - 1)) 1028 (dccp_hashinfo.ehash_size - 1))
1030 dccp_hashinfo.ehash_size--; 1029 dccp_hashinfo.ehash_size--;
@@ -1037,9 +1036,10 @@ static int __init dccp_init(void)
1037 goto out_free_bind_bucket_cachep; 1036 goto out_free_bind_bucket_cachep;
1038 } 1037 }
1039 1038
1040 for (i = 0; i < (dccp_hashinfo.ehash_size << 1); i++) { 1039 for (i = 0; i < dccp_hashinfo.ehash_size; i++) {
1041 rwlock_init(&dccp_hashinfo.ehash[i].lock); 1040 rwlock_init(&dccp_hashinfo.ehash[i].lock);
1042 INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain); 1041 INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain);
1042 INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].twchain);
1043 } 1043 }
1044 1044
1045 bhash_order = ehash_order; 1045 bhash_order = ehash_order;
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 9cd53addb784..8aa7d51e6881 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -778,7 +778,7 @@ next_normal:
778 struct inet_timewait_sock *tw; 778 struct inet_timewait_sock *tw;
779 779
780 inet_twsk_for_each(tw, node, 780 inet_twsk_for_each(tw, node,
781 &hashinfo->ehash[i + hashinfo->ehash_size].chain) { 781 &head->twchain) {
782 782
783 if (num < s_num) 783 if (num < s_num)
784 goto next_dying; 784 goto next_dying;
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 8c79c8a4ea5c..150ace18dc75 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -212,7 +212,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
212 write_lock(&head->lock); 212 write_lock(&head->lock);
213 213
214 /* Check TIME-WAIT sockets first. */ 214 /* Check TIME-WAIT sockets first. */
215 sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) { 215 sk_for_each(sk2, node, &head->twchain) {
216 tw = inet_twsk(sk2); 216 tw = inet_twsk(sk2);
217 217
218 if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) { 218 if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 9f414e35c488..a73cf93cee36 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -78,8 +78,8 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
78 if (__sk_del_node_init(sk)) 78 if (__sk_del_node_init(sk))
79 sock_prot_dec_use(sk->sk_prot); 79 sock_prot_dec_use(sk->sk_prot);
80 80
81 /* Step 3: Hash TW into TIMEWAIT half of established hash table. */ 81 /* Step 3: Hash TW into TIMEWAIT chain. */
82 inet_twsk_add_node(tw, &(ehead + hashinfo->ehash_size)->chain); 82 inet_twsk_add_node(tw, &ehead->twchain);
83 atomic_inc(&tw->tw_refcnt); 83 atomic_inc(&tw->tw_refcnt);
84 84
85 write_unlock(&ehead->lock); 85 write_unlock(&ehead->lock);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index b67e0dd743be..5bd43d7294fd 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2415,10 +2415,11 @@ void __init tcp_init(void)
2415 &tcp_hashinfo.ehash_size, 2415 &tcp_hashinfo.ehash_size,
2416 NULL, 2416 NULL,
2417 0); 2417 0);
2418 tcp_hashinfo.ehash_size = (1 << tcp_hashinfo.ehash_size) >> 1; 2418 tcp_hashinfo.ehash_size = 1 << tcp_hashinfo.ehash_size;
2419 for (i = 0; i < (tcp_hashinfo.ehash_size << 1); i++) { 2419 for (i = 0; i < tcp_hashinfo.ehash_size; i++) {
2420 rwlock_init(&tcp_hashinfo.ehash[i].lock); 2420 rwlock_init(&tcp_hashinfo.ehash[i].lock);
2421 INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].chain); 2421 INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].chain);
2422 INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].twchain);
2422 } 2423 }
2423 2424
2424 tcp_hashinfo.bhash = 2425 tcp_hashinfo.bhash =
@@ -2475,7 +2476,7 @@ void __init tcp_init(void)
2475 2476
2476 printk(KERN_INFO "TCP: Hash tables configured " 2477 printk(KERN_INFO "TCP: Hash tables configured "
2477 "(established %d bind %d)\n", 2478 "(established %d bind %d)\n",
2478 tcp_hashinfo.ehash_size << 1, tcp_hashinfo.bhash_size); 2479 tcp_hashinfo.ehash_size, tcp_hashinfo.bhash_size);
2479 2480
2480 tcp_register_congestion_control(&tcp_reno); 2481 tcp_register_congestion_control(&tcp_reno);
2481} 2482}
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 383e4b52dbde..f51d6404c61c 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2051,7 +2051,7 @@ static void *established_get_first(struct seq_file *seq)
2051 } 2051 }
2052 st->state = TCP_SEQ_STATE_TIME_WAIT; 2052 st->state = TCP_SEQ_STATE_TIME_WAIT;
2053 inet_twsk_for_each(tw, node, 2053 inet_twsk_for_each(tw, node,
2054 &tcp_hashinfo.ehash[st->bucket + tcp_hashinfo.ehash_size].chain) { 2054 &tcp_hashinfo.ehash[st->bucket].twchain) {
2055 if (tw->tw_family != st->family) { 2055 if (tw->tw_family != st->family) {
2056 continue; 2056 continue;
2057 } 2057 }
@@ -2107,7 +2107,7 @@ get_tw:
2107 } 2107 }
2108 2108
2109 st->state = TCP_SEQ_STATE_TIME_WAIT; 2109 st->state = TCP_SEQ_STATE_TIME_WAIT;
2110 tw = tw_head(&tcp_hashinfo.ehash[st->bucket + tcp_hashinfo.ehash_size].chain); 2110 tw = tw_head(&tcp_hashinfo.ehash[st->bucket].twchain);
2111 goto get_tw; 2111 goto get_tw;
2112found: 2112found:
2113 cur = sk; 2113 cur = sk;
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index b7e5bae0e347..e61116949bee 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -79,7 +79,7 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
79 goto hit; /* You sunk my battleship! */ 79 goto hit; /* You sunk my battleship! */
80 } 80 }
81 /* Must check for a TIME_WAIT'er before going to listener hash. */ 81 /* Must check for a TIME_WAIT'er before going to listener hash. */
82 sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) { 82 sk_for_each(sk, node, &head->twchain) {
83 const struct inet_timewait_sock *tw = inet_twsk(sk); 83 const struct inet_timewait_sock *tw = inet_twsk(sk);
84 84
85 if(*((__portpair *)&(tw->tw_dport)) == ports && 85 if(*((__portpair *)&(tw->tw_dport)) == ports &&
@@ -183,7 +183,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
183 write_lock(&head->lock); 183 write_lock(&head->lock);
184 184
185 /* Check TIME-WAIT sockets first. */ 185 /* Check TIME-WAIT sockets first. */
186 sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) { 186 sk_for_each(sk2, node, &head->twchain) {
187 const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2); 187 const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2);
188 188
189 tw = inet_twsk(sk2); 189 tw = inet_twsk(sk2);