aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_minisocks.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@ghostprotocols.net>2005-08-09 23:09:46 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:42:18 -0400
commite48c414ee61f4ac8d5cff2973e66a7cbc8a93aa5 (patch)
treec4656efe48b75adf5742514c3e4286007f20bdca /net/ipv4/tcp_minisocks.c
parent8feaf0c0a5488b3d898a9c207eb6678f44ba3f26 (diff)
[INET]: Generalise the TCP sock ID lookup routines
And also some TIME_WAIT functions. [acme@toy net-2.6.14]$ grep built-in /tmp/before.size /tmp/after.size /tmp/before.size: 282955 13122 9312 305389 4a8ed net/ipv4/built-in.o /tmp/after.size: 281566 13122 9312 304000 4a380 net/ipv4/built-in.o [acme@toy net-2.6.14]$ I kept them still inlined, will uninline at some point to see what would be the performance difference. Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
-rw-r--r--net/ipv4/tcp_minisocks.c78
1 files changed, 4 insertions, 74 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 5b5a49335fbb..4112f7a6d108 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -56,42 +56,6 @@ static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win)
56 56
57int tcp_tw_count; 57int tcp_tw_count;
58 58
59
60/* Must be called with locally disabled BHs. */
61static void tcp_timewait_kill(struct inet_timewait_sock *tw)
62{
63 struct inet_bind_hashbucket *bhead;
64 struct inet_bind_bucket *tb;
65 /* Unlink from established hashes. */
66 struct inet_ehash_bucket *ehead = &tcp_hashinfo.ehash[tw->tw_hashent];
67
68 write_lock(&ehead->lock);
69 if (hlist_unhashed(&tw->tw_node)) {
70 write_unlock(&ehead->lock);
71 return;
72 }
73 __hlist_del(&tw->tw_node);
74 sk_node_init(&tw->tw_node);
75 write_unlock(&ehead->lock);
76
77 /* Disassociate with bind bucket. */
78 bhead = &tcp_hashinfo.bhash[inet_bhashfn(tw->tw_num, tcp_hashinfo.bhash_size)];
79 spin_lock(&bhead->lock);
80 tb = tw->tw_tb;
81 __hlist_del(&tw->tw_bind_node);
82 tw->tw_tb = NULL;
83 inet_bind_bucket_destroy(tcp_hashinfo.bind_bucket_cachep, tb);
84 spin_unlock(&bhead->lock);
85
86#ifdef SOCK_REFCNT_DEBUG
87 if (atomic_read(&tw->tw_refcnt) != 1) {
88 printk(KERN_DEBUG "%s timewait_sock %p refcnt=%d\n",
89 tw->tw_prot->name, tw, atomic_read(&tw->tw_refcnt));
90 }
91#endif
92 inet_twsk_put(tw);
93}
94
95/* 59/*
96 * * Main purpose of TIME-WAIT state is to close connection gracefully, 60 * * Main purpose of TIME-WAIT state is to close connection gracefully,
97 * when one of ends sits in LAST-ACK or CLOSING retransmitting FIN 61 * when one of ends sits in LAST-ACK or CLOSING retransmitting FIN
@@ -290,40 +254,6 @@ kill:
290 return TCP_TW_SUCCESS; 254 return TCP_TW_SUCCESS;
291} 255}
292 256
293/* Enter the time wait state. This is called with locally disabled BH.
294 * Essentially we whip up a timewait bucket, copy the
295 * relevant info into it from the SK, and mess with hash chains
296 * and list linkage.
297 */
298static void __tcp_tw_hashdance(struct sock *sk, struct inet_timewait_sock *tw)
299{
300 const struct inet_sock *inet = inet_sk(sk);
301 struct inet_ehash_bucket *ehead = &tcp_hashinfo.ehash[sk->sk_hashent];
302 struct inet_bind_hashbucket *bhead;
303 /* Step 1: Put TW into bind hash. Original socket stays there too.
304 Note, that any socket with inet->num != 0 MUST be bound in
305 binding cache, even if it is closed.
306 */
307 bhead = &tcp_hashinfo.bhash[inet_bhashfn(inet->num, tcp_hashinfo.bhash_size)];
308 spin_lock(&bhead->lock);
309 tw->tw_tb = inet->bind_hash;
310 BUG_TRAP(inet->bind_hash);
311 inet_twsk_add_bind_node(tw, &tw->tw_tb->owners);
312 spin_unlock(&bhead->lock);
313
314 write_lock(&ehead->lock);
315
316 /* Step 2: Remove SK from established hash. */
317 if (__sk_del_node_init(sk))
318 sock_prot_dec_use(sk->sk_prot);
319
320 /* Step 3: Hash TW into TIMEWAIT half of established hash table. */
321 inet_twsk_add_node(tw, &(ehead + tcp_hashinfo.ehash_size)->chain);
322 atomic_inc(&tw->tw_refcnt);
323
324 write_unlock(&ehead->lock);
325}
326
327/* 257/*
328 * Move a socket to time-wait or dead fin-wait-2 state. 258 * Move a socket to time-wait or dead fin-wait-2 state.
329 */ 259 */
@@ -381,7 +311,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
381 tw->tw_ipv6only = 0; 311 tw->tw_ipv6only = 0;
382#endif 312#endif
383 /* Linkage updates. */ 313 /* Linkage updates. */
384 __tcp_tw_hashdance(sk, tw); 314 __inet_twsk_hashdance(tw, sk, &tcp_hashinfo);
385 315
386 /* Get the TIME_WAIT timeout firing. */ 316 /* Get the TIME_WAIT timeout firing. */
387 if (timeo < rto) 317 if (timeo < rto)
@@ -448,7 +378,7 @@ rescan:
448 inet_twsk_for_each_inmate(tw, node, &tcp_tw_death_row[slot]) { 378 inet_twsk_for_each_inmate(tw, node, &tcp_tw_death_row[slot]) {
449 __inet_twsk_del_dead_node(tw); 379 __inet_twsk_del_dead_node(tw);
450 spin_unlock(&tw_death_lock); 380 spin_unlock(&tw_death_lock);
451 tcp_timewait_kill(tw); 381 __inet_twsk_kill(tw, &tcp_hashinfo);
452 inet_twsk_put(tw); 382 inet_twsk_put(tw);
453 killed++; 383 killed++;
454 spin_lock(&tw_death_lock); 384 spin_lock(&tw_death_lock);
@@ -544,7 +474,7 @@ void tcp_tw_deschedule(struct inet_timewait_sock *tw)
544 del_timer(&tcp_tw_timer); 474 del_timer(&tcp_tw_timer);
545 } 475 }
546 spin_unlock(&tw_death_lock); 476 spin_unlock(&tw_death_lock);
547 tcp_timewait_kill(tw); 477 __inet_twsk_kill(tw, &tcp_hashinfo);
548} 478}
549 479
550/* Short-time timewait calendar */ 480/* Short-time timewait calendar */
@@ -653,7 +583,7 @@ void tcp_twcal_tick(unsigned long dummy)
653 inet_twsk_for_each_inmate_safe(tw, node, safe, 583 inet_twsk_for_each_inmate_safe(tw, node, safe,
654 &tcp_twcal_row[slot]) { 584 &tcp_twcal_row[slot]) {
655 __inet_twsk_del_dead_node(tw); 585 __inet_twsk_del_dead_node(tw);
656 tcp_timewait_kill(tw); 586 __inet_twsk_kill(tw, &tcp_hashinfo);
657 inet_twsk_put(tw); 587 inet_twsk_put(tw);
658 killed++; 588 killed++;
659 } 589 }