Skip to content

Commit ec94c26

Browse files
edumazetdavem330
authored andcommitted
tcp/dccp: avoid one atomic operation for timewait hashdance
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() Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1e75701 commit ec94c26

File tree

4 files changed

+23
-22
lines changed

4 files changed

+23
-22
lines changed

include/net/inet_timewait_sock.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk,
9393
struct inet_timewait_death_row *dr,
9494
const int state);
9595

96-
void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
97-
struct inet_hashinfo *hashinfo);
96+
void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
97+
struct inet_hashinfo *hashinfo);
9898

9999
void __inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo,
100100
bool rearm);

net/dccp/minisocks.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,10 @@ void dccp_time_wait(struct sock *sk, int state, int timeo)
6363
*/
6464
local_bh_disable();
6565
inet_twsk_schedule(tw, timeo);
66-
/* Linkage updates. */
67-
__inet_twsk_hashdance(tw, sk, &dccp_hashinfo);
68-
inet_twsk_put(tw);
66+
/* Linkage updates.
67+
* Note that access to tw after this point is illegal.
68+
*/
69+
inet_twsk_hashdance(tw, sk, &dccp_hashinfo);
6970
local_bh_enable();
7071
} else {
7172
/* Sorry, if we're out of memory, just CLOSE this

net/ipv4/inet_timewait_sock.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw,
9797
* Essentially we whip up a timewait bucket, copy the relevant info into it
9898
* from the SK, and mess with hash chains and list linkage.
9999
*/
100-
void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
100+
void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
101101
struct inet_hashinfo *hashinfo)
102102
{
103103
const struct inet_sock *inet = inet_sk(sk);
@@ -119,27 +119,26 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
119119

120120
spin_lock(lock);
121121

122-
/*
123-
* Step 2: Hash TW into tcp ehash chain.
124-
* Notes :
125-
* - tw_refcnt is set to 4 because :
126-
* - We have one reference from bhash chain.
127-
* - We have one reference from ehash chain.
128-
* - We have one reference from timer.
129-
* - One reference for ourself (our caller will release it).
130-
* We can use atomic_set() because prior spin_lock()/spin_unlock()
131-
* committed into memory all tw fields.
132-
*/
133-
refcount_set(&tw->tw_refcnt, 4);
134122
inet_twsk_add_node_rcu(tw, &ehead->chain);
135123

136124
/* Step 3: Remove SK from hash chain */
137125
if (__sk_nulls_del_node_init_rcu(sk))
138126
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
139127

140128
spin_unlock(lock);
129+
130+
/* tw_refcnt is set to 3 because we have :
131+
* - one reference for bhash chain.
132+
* - one reference for ehash chain.
133+
* - one reference for timer.
134+
* We can use atomic_set() because prior spin_lock()/spin_unlock()
135+
* committed into memory all tw fields.
136+
* Also note that after this point, we lost our implicit reference
137+
* so we are not allowed to use tw anymore.
138+
*/
139+
refcount_set(&tw->tw_refcnt, 3);
141140
}
142-
EXPORT_SYMBOL_GPL(__inet_twsk_hashdance);
141+
EXPORT_SYMBOL_GPL(inet_twsk_hashdance);
143142

144143
static void tw_timer_handler(struct timer_list *t)
145144
{

net/ipv4/tcp_minisocks.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,9 +316,10 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
316316
*/
317317
local_bh_disable();
318318
inet_twsk_schedule(tw, timeo);
319-
/* Linkage updates. */
320-
__inet_twsk_hashdance(tw, sk, &tcp_hashinfo);
321-
inet_twsk_put(tw);
319+
/* Linkage updates.
320+
* Note that access to tw after this point is illegal.
321+
*/
322+
inet_twsk_hashdance(tw, sk, &tcp_hashinfo);
322323
local_bh_enable();
323324
} else {
324325
/* Sorry, if we're out of memory, just CLOSE this

0 commit comments

Comments
 (0)