aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index d3b691f3a9e8..c31badfee806 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1904,7 +1904,9 @@ static int tso_fragment(struct sock *sk, enum tcp_queue tcp_queue,
1904 * This algorithm is from John Heffner. 1904 * This algorithm is from John Heffner.
1905 */ 1905 */
1906static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb, 1906static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,
1907 bool *is_cwnd_limited, u32 max_segs) 1907 bool *is_cwnd_limited,
1908 bool *is_rwnd_limited,
1909 u32 max_segs)
1908{ 1910{
1909 const struct inet_connection_sock *icsk = inet_csk(sk); 1911 const struct inet_connection_sock *icsk = inet_csk(sk);
1910 u32 send_win, cong_win, limit, in_flight; 1912 u32 send_win, cong_win, limit, in_flight;
@@ -1913,9 +1915,6 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,
1913 int win_divisor; 1915 int win_divisor;
1914 s64 delta; 1916 s64 delta;
1915 1917
1916 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
1917 goto send_now;
1918
1919 if (icsk->icsk_ca_state >= TCP_CA_Recovery) 1918 if (icsk->icsk_ca_state >= TCP_CA_Recovery)
1920 goto send_now; 1919 goto send_now;
1921 1920
@@ -1981,10 +1980,27 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,
1981 if ((s64)(delta - (u64)NSEC_PER_USEC * (tp->srtt_us >> 4)) < 0) 1980 if ((s64)(delta - (u64)NSEC_PER_USEC * (tp->srtt_us >> 4)) < 0)
1982 goto send_now; 1981 goto send_now;
1983 1982
1984 /* Ok, it looks like it is advisable to defer. */ 1983 /* Ok, it looks like it is advisable to defer.
1984 * Three cases are tracked :
1985 * 1) We are cwnd-limited
1986 * 2) We are rwnd-limited
1987 * 3) We are application limited.
1988 */
1989 if (cong_win < send_win) {
1990 if (cong_win <= skb->len) {
1991 *is_cwnd_limited = true;
1992 return true;
1993 }
1994 } else {
1995 if (send_win <= skb->len) {
1996 *is_rwnd_limited = true;
1997 return true;
1998 }
1999 }
1985 2000
1986 if (cong_win < send_win && cong_win <= skb->len) 2001 /* If this packet won't get more data, do not wait. */
1987 *is_cwnd_limited = true; 2002 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
2003 goto send_now;
1988 2004
1989 return true; 2005 return true;
1990 2006
@@ -2365,7 +2381,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
2365 } else { 2381 } else {
2366 if (!push_one && 2382 if (!push_one &&
2367 tcp_tso_should_defer(sk, skb, &is_cwnd_limited, 2383 tcp_tso_should_defer(sk, skb, &is_cwnd_limited,
2368 max_segs)) 2384 &is_rwnd_limited, max_segs))
2369 break; 2385 break;
2370 } 2386 }
2371 2387
@@ -2503,15 +2519,18 @@ void tcp_send_loss_probe(struct sock *sk)
2503 goto rearm_timer; 2519 goto rearm_timer;
2504 } 2520 }
2505 skb = skb_rb_last(&sk->tcp_rtx_queue); 2521 skb = skb_rb_last(&sk->tcp_rtx_queue);
2522 if (unlikely(!skb)) {
2523 WARN_ONCE(tp->packets_out,
2524 "invalid inflight: %u state %u cwnd %u mss %d\n",
2525 tp->packets_out, sk->sk_state, tp->snd_cwnd, mss);
2526 inet_csk(sk)->icsk_pending = 0;
2527 return;
2528 }
2506 2529
2507 /* At most one outstanding TLP retransmission. */ 2530 /* At most one outstanding TLP retransmission. */
2508 if (tp->tlp_high_seq) 2531 if (tp->tlp_high_seq)
2509 goto rearm_timer; 2532 goto rearm_timer;
2510 2533
2511 /* Retransmit last segment. */
2512 if (WARN_ON(!skb))
2513 goto rearm_timer;
2514
2515 if (skb_still_in_host_queue(sk, skb)) 2534 if (skb_still_in_host_queue(sk, skb))
2516 goto rearm_timer; 2535 goto rearm_timer;
2517 2536
@@ -2929,7 +2948,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
2929 TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS; 2948 TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS;
2930 trace_tcp_retransmit_skb(sk, skb); 2949 trace_tcp_retransmit_skb(sk, skb);
2931 } else if (err != -EBUSY) { 2950 } else if (err != -EBUSY) {
2932 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL); 2951 NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL, segs);
2933 } 2952 }
2934 return err; 2953 return err;
2935} 2954}