diff options
| author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-08-09 23:07:13 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:40:29 -0400 |
| commit | 2d8c4ce51903636ce0f60addc8134aa50ab8fa76 (patch) | |
| tree | 1ea4d4faf831b832489b30b13d8910777020feed /net | |
| parent | ff21d5774b4a186c98be6398eacde75d896db804 (diff) | |
[INET]: Generalise tcp_bind_hash & tcp_inherit_port
This required moving tcp_bucket_cachep to inet_hashinfo.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv4/inet_hashtables.c | 40 | ||||
| -rw-r--r-- | net/ipv4/tcp.c | 4 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 68 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 6 |
4 files changed, 47 insertions, 71 deletions
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 343a890bd617..33d6cbe32cdc 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/config.h> | 16 | #include <linux/config.h> |
| 17 | #include <linux/module.h> | ||
| 17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 18 | 19 | ||
| 19 | #include <net/inet_hashtables.h> | 20 | #include <net/inet_hashtables.h> |
| @@ -49,3 +50,42 @@ void inet_bind_bucket_destroy(kmem_cache_t *cachep, struct inet_bind_bucket *tb) | |||
| 49 | kmem_cache_free(cachep, tb); | 50 | kmem_cache_free(cachep, tb); |
| 50 | } | 51 | } |
| 51 | } | 52 | } |
| 53 | |||
| 54 | void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, | ||
| 55 | const unsigned short snum) | ||
| 56 | { | ||
| 57 | struct inet_sock *inet = inet_sk(sk); | ||
| 58 | inet->num = snum; | ||
| 59 | sk_add_bind_node(sk, &tb->owners); | ||
| 60 | inet->bind_hash = tb; | ||
| 61 | } | ||
| 62 | |||
| 63 | EXPORT_SYMBOL(inet_bind_hash); | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Get rid of any references to a local port held by the given sock. | ||
| 67 | */ | ||
| 68 | static void __inet_put_port(struct inet_hashinfo *hashinfo, struct sock *sk) | ||
| 69 | { | ||
| 70 | struct inet_sock *inet = inet_sk(sk); | ||
| 71 | const int bhash = inet_bhashfn(inet->num, hashinfo->bhash_size); | ||
| 72 | struct inet_bind_hashbucket *head = &hashinfo->bhash[bhash]; | ||
| 73 | struct inet_bind_bucket *tb; | ||
| 74 | |||
| 75 | spin_lock(&head->lock); | ||
| 76 | tb = inet->bind_hash; | ||
| 77 | __sk_del_bind_node(sk); | ||
| 78 | inet->bind_hash = NULL; | ||
| 79 | inet->num = 0; | ||
| 80 | inet_bind_bucket_destroy(hashinfo->bind_bucket_cachep, tb); | ||
| 81 | spin_unlock(&head->lock); | ||
| 82 | } | ||
| 83 | |||
| 84 | void inet_put_port(struct inet_hashinfo *hashinfo, struct sock *sk) | ||
| 85 | { | ||
| 86 | local_bh_disable(); | ||
| 87 | __inet_put_port(hashinfo, sk); | ||
| 88 | local_bh_enable(); | ||
| 89 | } | ||
| 90 | |||
| 91 | EXPORT_SYMBOL(inet_put_port); | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index e54a410ca701..38c04c1a754c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -271,10 +271,6 @@ int sysctl_tcp_fin_timeout = TCP_FIN_TIMEOUT; | |||
| 271 | 271 | ||
| 272 | DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics); | 272 | DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics); |
| 273 | 273 | ||
| 274 | kmem_cache_t *tcp_bucket_cachep; | ||
| 275 | |||
| 276 | EXPORT_SYMBOL_GPL(tcp_bucket_cachep); | ||
| 277 | |||
| 278 | kmem_cache_t *tcp_timewait_cachep; | 274 | kmem_cache_t *tcp_timewait_cachep; |
| 279 | 275 | ||
| 280 | atomic_t tcp_orphan_count = ATOMIC_INIT(0); | 276 | atomic_t tcp_orphan_count = ATOMIC_INIT(0); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 10a9b3ae3442..40fe4f5fca1c 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -104,37 +104,6 @@ struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { | |||
| 104 | int sysctl_local_port_range[2] = { 1024, 4999 }; | 104 | int sysctl_local_port_range[2] = { 1024, 4999 }; |
| 105 | int tcp_port_rover = 1024 - 1; | 105 | int tcp_port_rover = 1024 - 1; |
| 106 | 106 | ||
| 107 | /* Caller must disable local BH processing. */ | ||
| 108 | static __inline__ void __tcp_inherit_port(struct sock *sk, struct sock *child) | ||
| 109 | { | ||
| 110 | struct inet_bind_hashbucket *head = | ||
| 111 | &tcp_bhash[inet_bhashfn(inet_sk(child)->num, | ||
| 112 | tcp_bhash_size)]; | ||
| 113 | struct inet_bind_bucket *tb; | ||
| 114 | |||
| 115 | spin_lock(&head->lock); | ||
| 116 | tb = inet_sk(sk)->bind_hash; | ||
| 117 | sk_add_bind_node(child, &tb->owners); | ||
| 118 | inet_sk(child)->bind_hash = tb; | ||
| 119 | spin_unlock(&head->lock); | ||
| 120 | } | ||
| 121 | |||
| 122 | inline void tcp_inherit_port(struct sock *sk, struct sock *child) | ||
| 123 | { | ||
| 124 | local_bh_disable(); | ||
| 125 | __tcp_inherit_port(sk, child); | ||
| 126 | local_bh_enable(); | ||
| 127 | } | ||
| 128 | |||
| 129 | void tcp_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, | ||
| 130 | const unsigned short snum) | ||
| 131 | { | ||
| 132 | struct inet_sock *inet = inet_sk(sk); | ||
| 133 | inet->num = snum; | ||
| 134 | sk_add_bind_node(sk, &tb->owners); | ||
| 135 | inet->bind_hash = tb; | ||
| 136 | } | ||
| 137 | |||
| 138 | static inline int tcp_bind_conflict(struct sock *sk, struct inet_bind_bucket *tb) | 107 | static inline int tcp_bind_conflict(struct sock *sk, struct inet_bind_bucket *tb) |
| 139 | { | 108 | { |
| 140 | const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk); | 109 | const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk); |
| @@ -248,7 +217,7 @@ tb_not_found: | |||
| 248 | tb->fastreuse = 0; | 217 | tb->fastreuse = 0; |
| 249 | success: | 218 | success: |
| 250 | if (!inet_sk(sk)->bind_hash) | 219 | if (!inet_sk(sk)->bind_hash) |
| 251 | tcp_bind_hash(sk, tb, snum); | 220 | inet_bind_hash(sk, tb, snum); |
| 252 | BUG_TRAP(inet_sk(sk)->bind_hash == tb); | 221 | BUG_TRAP(inet_sk(sk)->bind_hash == tb); |
| 253 | ret = 0; | 222 | ret = 0; |
| 254 | 223 | ||
| @@ -259,32 +228,6 @@ fail: | |||
| 259 | return ret; | 228 | return ret; |
| 260 | } | 229 | } |
| 261 | 230 | ||
| 262 | /* Get rid of any references to a local port held by the | ||
| 263 | * given sock. | ||
| 264 | */ | ||
| 265 | static void __tcp_put_port(struct sock *sk) | ||
| 266 | { | ||
| 267 | struct inet_sock *inet = inet_sk(sk); | ||
| 268 | struct inet_bind_hashbucket *head = &tcp_bhash[inet_bhashfn(inet->num, | ||
| 269 | tcp_bhash_size)]; | ||
| 270 | struct inet_bind_bucket *tb; | ||
| 271 | |||
| 272 | spin_lock(&head->lock); | ||
| 273 | tb = inet->bind_hash; | ||
| 274 | __sk_del_bind_node(sk); | ||
| 275 | inet->bind_hash = NULL; | ||
| 276 | inet->num = 0; | ||
| 277 | inet_bind_bucket_destroy(tcp_bucket_cachep, tb); | ||
| 278 | spin_unlock(&head->lock); | ||
| 279 | } | ||
| 280 | |||
| 281 | void tcp_put_port(struct sock *sk) | ||
| 282 | { | ||
| 283 | local_bh_disable(); | ||
| 284 | __tcp_put_port(sk); | ||
| 285 | local_bh_enable(); | ||
| 286 | } | ||
| 287 | |||
| 288 | /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it can be very bad on SMP. | 231 | /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it can be very bad on SMP. |
| 289 | * Look, when several writers sleep and reader wakes them up, all but one | 232 | * Look, when several writers sleep and reader wakes them up, all but one |
| 290 | * immediately hit write lock and grab all the cpus. Exclusive sleep solves | 233 | * immediately hit write lock and grab all the cpus. Exclusive sleep solves |
| @@ -678,7 +621,7 @@ ok: | |||
| 678 | hint += i; | 621 | hint += i; |
| 679 | 622 | ||
| 680 | /* Head lock still held and bh's disabled */ | 623 | /* Head lock still held and bh's disabled */ |
| 681 | tcp_bind_hash(sk, tb, port); | 624 | inet_bind_hash(sk, tb, port); |
| 682 | if (sk_unhashed(sk)) { | 625 | if (sk_unhashed(sk)) { |
| 683 | inet_sk(sk)->sport = htons(port); | 626 | inet_sk(sk)->sport = htons(port); |
| 684 | __tcp_v4_hash(sk, 0); | 627 | __tcp_v4_hash(sk, 0); |
| @@ -1537,7 +1480,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
| 1537 | tcp_initialize_rcv_mss(newsk); | 1480 | tcp_initialize_rcv_mss(newsk); |
| 1538 | 1481 | ||
| 1539 | __tcp_v4_hash(newsk, 0); | 1482 | __tcp_v4_hash(newsk, 0); |
| 1540 | __tcp_inherit_port(sk, newsk); | 1483 | __inet_inherit_port(&tcp_hashinfo, sk, newsk); |
| 1541 | 1484 | ||
| 1542 | return newsk; | 1485 | return newsk; |
| 1543 | 1486 | ||
| @@ -1942,7 +1885,7 @@ int tcp_v4_destroy_sock(struct sock *sk) | |||
| 1942 | 1885 | ||
| 1943 | /* Clean up a referenced TCP bind bucket. */ | 1886 | /* Clean up a referenced TCP bind bucket. */ |
| 1944 | if (inet_sk(sk)->bind_hash) | 1887 | if (inet_sk(sk)->bind_hash) |
| 1945 | tcp_put_port(sk); | 1888 | inet_put_port(&tcp_hashinfo, sk); |
| 1946 | 1889 | ||
| 1947 | /* | 1890 | /* |
| 1948 | * If sendmsg cached page exists, toss it. | 1891 | * If sendmsg cached page exists, toss it. |
| @@ -2486,14 +2429,11 @@ void __init tcp_v4_init(struct net_proto_family *ops) | |||
| 2486 | } | 2429 | } |
| 2487 | 2430 | ||
| 2488 | EXPORT_SYMBOL(ipv4_specific); | 2431 | EXPORT_SYMBOL(ipv4_specific); |
| 2489 | EXPORT_SYMBOL(tcp_bind_hash); | ||
| 2490 | EXPORT_SYMBOL(inet_bind_bucket_create); | 2432 | EXPORT_SYMBOL(inet_bind_bucket_create); |
| 2491 | EXPORT_SYMBOL(tcp_hashinfo); | 2433 | EXPORT_SYMBOL(tcp_hashinfo); |
| 2492 | EXPORT_SYMBOL(tcp_inherit_port); | ||
| 2493 | EXPORT_SYMBOL(tcp_listen_wlock); | 2434 | EXPORT_SYMBOL(tcp_listen_wlock); |
| 2494 | EXPORT_SYMBOL(tcp_port_rover); | 2435 | EXPORT_SYMBOL(tcp_port_rover); |
| 2495 | EXPORT_SYMBOL(tcp_prot); | 2436 | EXPORT_SYMBOL(tcp_prot); |
| 2496 | EXPORT_SYMBOL(tcp_put_port); | ||
| 2497 | EXPORT_SYMBOL(tcp_unhash); | 2437 | EXPORT_SYMBOL(tcp_unhash); |
| 2498 | EXPORT_SYMBOL(tcp_v4_conn_request); | 2438 | EXPORT_SYMBOL(tcp_v4_conn_request); |
| 2499 | EXPORT_SYMBOL(tcp_v4_connect); | 2439 | EXPORT_SYMBOL(tcp_v4_connect); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index a8ca7ba06c1c..bfbedb56bce2 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -205,7 +205,7 @@ tb_not_found: | |||
| 205 | 205 | ||
| 206 | success: | 206 | success: |
| 207 | if (!inet_sk(sk)->bind_hash) | 207 | if (!inet_sk(sk)->bind_hash) |
| 208 | tcp_bind_hash(sk, tb, snum); | 208 | inet_bind_hash(sk, tb, snum); |
| 209 | BUG_TRAP(inet_sk(sk)->bind_hash == tb); | 209 | BUG_TRAP(inet_sk(sk)->bind_hash == tb); |
| 210 | ret = 0; | 210 | ret = 0; |
| 211 | 211 | ||
| @@ -597,7 +597,7 @@ ok: | |||
| 597 | hint += i; | 597 | hint += i; |
| 598 | 598 | ||
| 599 | /* Head lock still held and bh's disabled */ | 599 | /* Head lock still held and bh's disabled */ |
| 600 | tcp_bind_hash(sk, tb, port); | 600 | inet_bind_hash(sk, tb, port); |
| 601 | if (sk_unhashed(sk)) { | 601 | if (sk_unhashed(sk)) { |
| 602 | inet_sk(sk)->sport = htons(port); | 602 | inet_sk(sk)->sport = htons(port); |
| 603 | __tcp_v6_hash(sk); | 603 | __tcp_v6_hash(sk); |
| @@ -1536,7 +1536,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
| 1536 | newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; | 1536 | newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; |
| 1537 | 1537 | ||
| 1538 | __tcp_v6_hash(newsk); | 1538 | __tcp_v6_hash(newsk); |
| 1539 | tcp_inherit_port(sk, newsk); | 1539 | inet_inherit_port(&tcp_hashinfo, sk, newsk); |
| 1540 | 1540 | ||
| 1541 | return newsk; | 1541 | return newsk; |
| 1542 | 1542 | ||
