aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/tcp_output.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index cb95c7a9d1e7..5f4fb4d5bbd6 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1752,9 +1752,11 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
1752static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb, 1752static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,
1753 bool *is_cwnd_limited, u32 max_segs) 1753 bool *is_cwnd_limited, u32 max_segs)
1754{ 1754{
1755 struct tcp_sock *tp = tcp_sk(sk);
1756 const struct inet_connection_sock *icsk = inet_csk(sk); 1755 const struct inet_connection_sock *icsk = inet_csk(sk);
1757 u32 send_win, cong_win, limit, in_flight; 1756 u32 age, send_win, cong_win, limit, in_flight;
1757 struct tcp_sock *tp = tcp_sk(sk);
1758 struct skb_mstamp now;
1759 struct sk_buff *head;
1758 int win_divisor; 1760 int win_divisor;
1759 1761
1760 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) 1762 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
@@ -1808,6 +1810,13 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,
1808 goto send_now; 1810 goto send_now;
1809 } 1811 }
1810 1812
1813 head = tcp_write_queue_head(sk);
1814 skb_mstamp_get(&now);
1815 age = skb_mstamp_us_delta(&now, &head->skb_mstamp);
1816 /* If next ACK is likely to come too late (half srtt), do not defer */
1817 if (age < (tp->srtt_us >> 4))
1818 goto send_now;
1819
1811 /* Ok, it looks like it is advisable to defer. */ 1820 /* Ok, it looks like it is advisable to defer. */
1812 1821
1813 if (cong_win < send_win && cong_win < skb->len) 1822 if (cong_win < send_win && cong_win < skb->len)