diff options
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 8 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 14 | ||||
-rw-r--r-- | net/ipv4/tcp_timer.c | 6 |
3 files changed, 18 insertions, 10 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5bf2040b25b1..00a748d14062 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -417,10 +417,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
417 | 417 | ||
418 | if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */ | 418 | if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */ |
419 | tp->mtu_info = info; | 419 | tp->mtu_info = info; |
420 | if (!sock_owned_by_user(sk)) | 420 | if (!sock_owned_by_user(sk)) { |
421 | tcp_v4_mtu_reduced(sk); | 421 | tcp_v4_mtu_reduced(sk); |
422 | else | 422 | } else { |
423 | set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags); | 423 | if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags)) |
424 | sock_hold(sk); | ||
425 | } | ||
424 | goto out; | 426 | goto out; |
425 | } | 427 | } |
426 | 428 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 20dfd892c86f..d04632673a9e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -910,14 +910,18 @@ void tcp_release_cb(struct sock *sk) | |||
910 | if (flags & (1UL << TCP_TSQ_DEFERRED)) | 910 | if (flags & (1UL << TCP_TSQ_DEFERRED)) |
911 | tcp_tsq_handler(sk); | 911 | tcp_tsq_handler(sk); |
912 | 912 | ||
913 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) | 913 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) { |
914 | tcp_write_timer_handler(sk); | 914 | tcp_write_timer_handler(sk); |
915 | 915 | __sock_put(sk); | |
916 | if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED)) | 916 | } |
917 | if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED)) { | ||
917 | tcp_delack_timer_handler(sk); | 918 | tcp_delack_timer_handler(sk); |
918 | 919 | __sock_put(sk); | |
919 | if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) | 920 | } |
921 | if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) { | ||
920 | sk->sk_prot->mtu_reduced(sk); | 922 | sk->sk_prot->mtu_reduced(sk); |
923 | __sock_put(sk); | ||
924 | } | ||
921 | } | 925 | } |
922 | EXPORT_SYMBOL(tcp_release_cb); | 926 | EXPORT_SYMBOL(tcp_release_cb); |
923 | 927 | ||
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 6df36ad55a38..b774a03bd1dc 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -252,7 +252,8 @@ static void tcp_delack_timer(unsigned long data) | |||
252 | inet_csk(sk)->icsk_ack.blocked = 1; | 252 | inet_csk(sk)->icsk_ack.blocked = 1; |
253 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); | 253 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); |
254 | /* deleguate our work to tcp_release_cb() */ | 254 | /* deleguate our work to tcp_release_cb() */ |
255 | set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags); | 255 | if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags)) |
256 | sock_hold(sk); | ||
256 | } | 257 | } |
257 | bh_unlock_sock(sk); | 258 | bh_unlock_sock(sk); |
258 | sock_put(sk); | 259 | sock_put(sk); |
@@ -481,7 +482,8 @@ static void tcp_write_timer(unsigned long data) | |||
481 | tcp_write_timer_handler(sk); | 482 | tcp_write_timer_handler(sk); |
482 | } else { | 483 | } else { |
483 | /* deleguate our work to tcp_release_cb() */ | 484 | /* deleguate our work to tcp_release_cb() */ |
484 | set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags); | 485 | if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags)) |
486 | sock_hold(sk); | ||
485 | } | 487 | } |
486 | bh_unlock_sock(sk); | 488 | bh_unlock_sock(sk); |
487 | sock_put(sk); | 489 | sock_put(sk); |