diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/tcp_output.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0b88158dd4a7..eb73a1dccf56 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -1562,7 +1562,7 @@ static unsigned int tcp_mss_split_point(const struct sock *sk, | |||
1562 | static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, | 1562 | static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, |
1563 | const struct sk_buff *skb) | 1563 | const struct sk_buff *skb) |
1564 | { | 1564 | { |
1565 | u32 in_flight, cwnd; | 1565 | u32 in_flight, cwnd, halfcwnd; |
1566 | 1566 | ||
1567 | /* Don't be strict about the congestion window for the final FIN. */ | 1567 | /* Don't be strict about the congestion window for the final FIN. */ |
1568 | if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && | 1568 | if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && |
@@ -1571,10 +1571,14 @@ static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, | |||
1571 | 1571 | ||
1572 | in_flight = tcp_packets_in_flight(tp); | 1572 | in_flight = tcp_packets_in_flight(tp); |
1573 | cwnd = tp->snd_cwnd; | 1573 | cwnd = tp->snd_cwnd; |
1574 | if (in_flight < cwnd) | 1574 | if (in_flight >= cwnd) |
1575 | return (cwnd - in_flight); | 1575 | return 0; |
1576 | 1576 | ||
1577 | return 0; | 1577 | /* For better scheduling, ensure we have at least |
1578 | * 2 GSO packets in flight. | ||
1579 | */ | ||
1580 | halfcwnd = max(cwnd >> 1, 1U); | ||
1581 | return min(halfcwnd, cwnd - in_flight); | ||
1578 | } | 1582 | } |
1579 | 1583 | ||
1580 | /* Initialize TSO state of a skb. | 1584 | /* Initialize TSO state of a skb. |