tcp/dccp: avoid one atomic operation for timewait hashdance
Subsystems (3)
PATCH 1/1 tcp/dccp: avoid one atomic operation for timewait hashdance
From: Eric Dumazet <[email protected]>
First, rename __inet_twsk_hashdance() to inet_twsk_hashdance()
Then, remove one inet_twsk_put() by setting tw_refcnt to 3 instead of 4, but adding a fat warning that we do not have the right to access tw anymore after inet_twsk_hashdance()
---
include/net/inet_timewait_sock.h | 4 ++-- net/dccp/minisocks.c | 7 ++++--- net/ipv4/inet_timewait_sock.c | 27 +++++++++++++-------------- net/ipv4/tcp_minisocks.c | 7 ++++---
4 files changed, 23 insertions(+), 22 deletions(-)
include/net/inet_timewait_sock.h +2 -2
@@ -93,8 +93,8 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk,struct inet_timewait_death_row *dr, const int state); -void __inet_twsk_hashdance (struct inet_timewait_sock *tw,struct sock *sk, -struct inet_hashinfo *hashinfo); +void inet_twsk_hashdance (struct inet_timewait_sock *tw,struct sock *sk, +struct inet_hashinfo *hashinfo);void __inet_twsk_schedule (struct inet_timewait_sock *tw,int timeo,bool rearm);
net/dccp/minisocks.c +4 -3
@@ -63,9 +63,10 @@ void dccp_time_wait(struct sock *sk, int state, int timeo)*/ local_bh_disable ();inet_twsk_schedule (tw, timeo); -/* Linkage updates. */ -__inet_twsk_hashdance (tw, sk, &dccp_hashinfo); -inet_twsk_put (tw); +/* Linkage updates. +* Note that access to tw after this point is illegal. +*/ +inet_twsk_hashdance (tw, sk, &dccp_hashinfo);local_bh_enable (); }else {/* Sorry, if we're out of memory, just CLOSE this
net/ipv4/inet_timewait_sock.c +13 -14
@@ -97,7 +97,7 @@ static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw,* Essentially we whip up a timewait bucket, copy the relevant info into it * from the SK, and mess with hash chains and list linkage. */ -void __inet_twsk_hashdance (struct inet_timewait_sock *tw,struct sock *sk, +void inet_twsk_hashdance (struct inet_timewait_sock *tw,struct sock *sk,struct inet_hashinfo *hashinfo) {const struct inet_sock *inet =inet_sk (sk);
@@ -119,18 +119,6 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,spin_lock (lock); -/* -* Step 2: Hash TW into tcp ehash chain. -* Notes : -* - tw_refcnt is set to 4 because : -* - We have one reference from bhash chain. -* - We have one reference from ehash chain. -* - We have one reference from timer. -* - One reference for ourself (our caller will release it). -* We can use atomic_set() because prior spin_lock()/spin_unlock() -* committed into memory all tw fields. -*/ -refcount_set (&tw->tw_refcnt,4 );inet_twsk_add_node_rcu (tw, &ehead->chain);/* Step 3: Remove SK from hash chain */
@@ -138,8 +126,19 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,sock_prot_inuse_add (sock_net (sk), sk->sk_prot,-1 );spin_unlock (lock); + +/* tw_refcnt is set to 3 because we have : +* - one reference for bhash chain. +* - one reference for ehash chain. +* - one reference for timer. +* We can use atomic_set() because prior spin_lock()/spin_unlock() +* committed into memory all tw fields. +* Also note that after this point, we lost our implicit reference +* so we are not allowed to use tw anymore. +*/ +refcount_set (&tw->tw_refcnt,3 ); } -EXPORT_SYMBOL_GPL (__inet_twsk_hashdance); +EXPORT_SYMBOL_GPL (inet_twsk_hashdance);static void tw_timer_handler (struct timer_list *t) {
net/ipv4/tcp_minisocks.c +4 -3
@@ -316,9 +316,10 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)*/ local_bh_disable ();inet_twsk_schedule (tw, timeo); -/* Linkage updates. */ -__inet_twsk_hashdance (tw, sk, &tcp_hashinfo); -inet_twsk_put (tw); +/* Linkage updates. +* Note that access to tw after this point is illegal. +*/ +inet_twsk_hashdance (tw, sk, &tcp_hashinfo);local_bh_enable (); }else {/* Sorry, if we're out of memory, just CLOSE this
From: Eric Dumazet <[email protected]>
Date: Mon, 11 Dec 2017 21:25:12 -0800
Quoted 9 lines
From: Eric Dumazet <[email protected]>
First, rename
__inet_twsk_hashdance()toinet_twsk_hashdance()Then, remove one
inet_twsk_put()by settingtw_refcntto 3 instead of 4, but adding a fat warning that we do not have the right to access tw anymore afterinet_twsk_hashdance()Signed-off-by Eric Dumazet <[email protected]>
Applied, thanks Eric.