diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-12-08 23:19:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-08 23:19:53 -0500 |
commit | 2a8875e73ffb18165ceb245f99c2ccad77378051 (patch) | |
tree | f2a443bef4aec863b9b4143e528357518db0b89c /net/ipv4 | |
parent | 3cdaedae635b17ce23c738ce7d364b442310cdec (diff) |
[PATCH] tcp: documents timewait refcnt tricks
Adds kerneldoc for inet_twsk_unhash() & inet_twsk_bind_unhash().
With help from Randy Dunlap.
Suggested-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/inet_timewait_sock.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index bf4b1e2a4305..cc94cc2d8b2d 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c | |||
@@ -15,9 +15,13 @@ | |||
15 | #include <net/ip.h> | 15 | #include <net/ip.h> |
16 | 16 | ||
17 | 17 | ||
18 | /* | 18 | /** |
19 | * unhash a timewait socket from established hash | 19 | * inet_twsk_unhash - unhash a timewait socket from established hash |
20 | * lock must be hold by caller | 20 | * @tw: timewait socket |
21 | * | ||
22 | * unhash a timewait socket from established hash, if hashed. | ||
23 | * ehash lock must be held by caller. | ||
24 | * Returns 1 if caller should call inet_twsk_put() after lock release. | ||
21 | */ | 25 | */ |
22 | int inet_twsk_unhash(struct inet_timewait_sock *tw) | 26 | int inet_twsk_unhash(struct inet_timewait_sock *tw) |
23 | { | 27 | { |
@@ -26,12 +30,21 @@ int inet_twsk_unhash(struct inet_timewait_sock *tw) | |||
26 | 30 | ||
27 | hlist_nulls_del_rcu(&tw->tw_node); | 31 | hlist_nulls_del_rcu(&tw->tw_node); |
28 | sk_nulls_node_init(&tw->tw_node); | 32 | sk_nulls_node_init(&tw->tw_node); |
33 | /* | ||
34 | * We cannot call inet_twsk_put() ourself under lock, | ||
35 | * caller must call it for us. | ||
36 | */ | ||
29 | return 1; | 37 | return 1; |
30 | } | 38 | } |
31 | 39 | ||
32 | /* | 40 | /** |
33 | * unhash a timewait socket from bind hash | 41 | * inet_twsk_bind_unhash - unhash a timewait socket from bind hash |
34 | * lock must be hold by caller | 42 | * @tw: timewait socket |
43 | * @hashinfo: hashinfo pointer | ||
44 | * | ||
45 | * unhash a timewait socket from bind hash, if hashed. | ||
46 | * bind hash lock must be held by caller. | ||
47 | * Returns 1 if caller should call inet_twsk_put() after lock release. | ||
35 | */ | 48 | */ |
36 | int inet_twsk_bind_unhash(struct inet_timewait_sock *tw, | 49 | int inet_twsk_bind_unhash(struct inet_timewait_sock *tw, |
37 | struct inet_hashinfo *hashinfo) | 50 | struct inet_hashinfo *hashinfo) |
@@ -44,6 +57,10 @@ int inet_twsk_bind_unhash(struct inet_timewait_sock *tw, | |||
44 | __hlist_del(&tw->tw_bind_node); | 57 | __hlist_del(&tw->tw_bind_node); |
45 | tw->tw_tb = NULL; | 58 | tw->tw_tb = NULL; |
46 | inet_bind_bucket_destroy(hashinfo->bind_bucket_cachep, tb); | 59 | inet_bind_bucket_destroy(hashinfo->bind_bucket_cachep, tb); |
60 | /* | ||
61 | * We cannot call inet_twsk_put() ourself under lock, | ||
62 | * caller must call it for us. | ||
63 | */ | ||
47 | return 1; | 64 | return 1; |
48 | } | 65 | } |
49 | 66 | ||
@@ -139,7 +156,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, | |||
139 | 156 | ||
140 | /* | 157 | /* |
141 | * Notes : | 158 | * Notes : |
142 | * - We initially set tw_refcnt to 0 in inet_twsk_alloc() | 159 | * - We initially set tw_refcnt to 0 in inet_twsk_alloc() |
143 | * - We add one reference for the bhash link | 160 | * - We add one reference for the bhash link |
144 | * - We add one reference for the ehash link | 161 | * - We add one reference for the ehash link |
145 | * - We want this refcnt update done before allowing other | 162 | * - We want this refcnt update done before allowing other |
@@ -149,7 +166,6 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, | |||
149 | 166 | ||
150 | spin_unlock(lock); | 167 | spin_unlock(lock); |
151 | } | 168 | } |
152 | |||
153 | EXPORT_SYMBOL_GPL(__inet_twsk_hashdance); | 169 | EXPORT_SYMBOL_GPL(__inet_twsk_hashdance); |
154 | 170 | ||
155 | struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state) | 171 | struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state) |
@@ -190,7 +206,6 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat | |||
190 | 206 | ||
191 | return tw; | 207 | return tw; |
192 | } | 208 | } |
193 | |||
194 | EXPORT_SYMBOL_GPL(inet_twsk_alloc); | 209 | EXPORT_SYMBOL_GPL(inet_twsk_alloc); |
195 | 210 | ||
196 | /* Returns non-zero if quota exceeded. */ | 211 | /* Returns non-zero if quota exceeded. */ |
@@ -269,7 +284,6 @@ void inet_twdr_hangman(unsigned long data) | |||
269 | out: | 284 | out: |
270 | spin_unlock(&twdr->death_lock); | 285 | spin_unlock(&twdr->death_lock); |
271 | } | 286 | } |
272 | |||
273 | EXPORT_SYMBOL_GPL(inet_twdr_hangman); | 287 | EXPORT_SYMBOL_GPL(inet_twdr_hangman); |
274 | 288 | ||
275 | void inet_twdr_twkill_work(struct work_struct *work) | 289 | void inet_twdr_twkill_work(struct work_struct *work) |
@@ -300,7 +314,6 @@ void inet_twdr_twkill_work(struct work_struct *work) | |||
300 | spin_unlock_bh(&twdr->death_lock); | 314 | spin_unlock_bh(&twdr->death_lock); |
301 | } | 315 | } |
302 | } | 316 | } |
303 | |||
304 | EXPORT_SYMBOL_GPL(inet_twdr_twkill_work); | 317 | EXPORT_SYMBOL_GPL(inet_twdr_twkill_work); |
305 | 318 | ||
306 | /* These are always called from BH context. See callers in | 319 | /* These are always called from BH context. See callers in |
@@ -320,7 +333,6 @@ void inet_twsk_deschedule(struct inet_timewait_sock *tw, | |||
320 | spin_unlock(&twdr->death_lock); | 333 | spin_unlock(&twdr->death_lock); |
321 | __inet_twsk_kill(tw, twdr->hashinfo); | 334 | __inet_twsk_kill(tw, twdr->hashinfo); |
322 | } | 335 | } |
323 | |||
324 | EXPORT_SYMBOL(inet_twsk_deschedule); | 336 | EXPORT_SYMBOL(inet_twsk_deschedule); |
325 | 337 | ||
326 | void inet_twsk_schedule(struct inet_timewait_sock *tw, | 338 | void inet_twsk_schedule(struct inet_timewait_sock *tw, |
@@ -401,7 +413,6 @@ void inet_twsk_schedule(struct inet_timewait_sock *tw, | |||
401 | mod_timer(&twdr->tw_timer, jiffies + twdr->period); | 413 | mod_timer(&twdr->tw_timer, jiffies + twdr->period); |
402 | spin_unlock(&twdr->death_lock); | 414 | spin_unlock(&twdr->death_lock); |
403 | } | 415 | } |
404 | |||
405 | EXPORT_SYMBOL_GPL(inet_twsk_schedule); | 416 | EXPORT_SYMBOL_GPL(inet_twsk_schedule); |
406 | 417 | ||
407 | void inet_twdr_twcal_tick(unsigned long data) | 418 | void inet_twdr_twcal_tick(unsigned long data) |
@@ -462,7 +473,6 @@ out: | |||
462 | #endif | 473 | #endif |
463 | spin_unlock(&twdr->death_lock); | 474 | spin_unlock(&twdr->death_lock); |
464 | } | 475 | } |
465 | |||
466 | EXPORT_SYMBOL_GPL(inet_twdr_twcal_tick); | 476 | EXPORT_SYMBOL_GPL(inet_twdr_twcal_tick); |
467 | 477 | ||
468 | void inet_twsk_purge(struct inet_hashinfo *hashinfo, | 478 | void inet_twsk_purge(struct inet_hashinfo *hashinfo, |