diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 8f8527d41682..69ccbc1dde9c 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -415,6 +415,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
| 415 | !icsk->icsk_backoff) | 415 | !icsk->icsk_backoff) |
| 416 | break; | 416 | break; |
| 417 | 417 | ||
| 418 | if (sock_owned_by_user(sk)) | ||
| 419 | break; | ||
| 420 | |||
| 418 | icsk->icsk_backoff--; | 421 | icsk->icsk_backoff--; |
| 419 | inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) << | 422 | inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) << |
| 420 | icsk->icsk_backoff; | 423 | icsk->icsk_backoff; |
| @@ -429,11 +432,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
| 429 | if (remaining) { | 432 | if (remaining) { |
| 430 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 433 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
| 431 | remaining, TCP_RTO_MAX); | 434 | remaining, TCP_RTO_MAX); |
| 432 | } else if (sock_owned_by_user(sk)) { | ||
| 433 | /* RTO revert clocked out retransmission, | ||
| 434 | * but socket is locked. Will defer. */ | ||
| 435 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | ||
| 436 | HZ/20, TCP_RTO_MAX); | ||
| 437 | } else { | 435 | } else { |
| 438 | /* RTO revert clocked out retransmission. | 436 | /* RTO revert clocked out retransmission. |
| 439 | * Will retransmit now */ | 437 | * Will retransmit now */ |
