|
@@ -1562,7 +1562,7 @@ static unsigned int tcp_mss_split_point(const struct sock *sk,
|
|
|
static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp,
|
|
static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp,
|
|
|
const struct sk_buff *skb)
|
|
const struct sk_buff *skb)
|
|
|
{
|
|
{
|
|
|
- u32 in_flight, cwnd;
|
|
|
|
|
|
|
+ u32 in_flight, cwnd, halfcwnd;
|
|
|
|
|
|
|
|
/* Don't be strict about the congestion window for the final FIN. */
|
|
/* Don't be strict about the congestion window for the final FIN. */
|
|
|
if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) &&
|
|
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,
|
|
|
|
|
|
|
|
in_flight = tcp_packets_in_flight(tp);
|
|
in_flight = tcp_packets_in_flight(tp);
|
|
|
cwnd = tp->snd_cwnd;
|
|
cwnd = tp->snd_cwnd;
|
|
|
- if (in_flight < cwnd)
|
|
|
|
|
- return (cwnd - in_flight);
|
|
|
|
|
|
|
+ if (in_flight >= cwnd)
|
|
|
|
|
+ return 0;
|
|
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+ /* For better scheduling, ensure we have at least
|
|
|
|
|
+ * 2 GSO packets in flight.
|
|
|
|
|
+ */
|
|
|
|
|
+ halfcwnd = max(cwnd >> 1, 1U);
|
|
|
|
|
+ return min(halfcwnd, cwnd - in_flight);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Initialize TSO state of a skb.
|
|
/* Initialize TSO state of a skb.
|