|
@@ -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)
|
|
|
{
|