The core of what I am now testing is:
+/* RFC2861 Check whether we are limited by application or congestion window + * This is the inverse of tcp_tso_should_defer + */ +static inline int tcp_cwnd_full(const struct tcp_sock *tp, u32 in_flight, + u32 ack_seq) +{ + u32 left; + + if (in_flight >= tp->snd_cwnd) + return 1; + + left = tp->snd_cwnd - in_flight; + if (sysctl_tcp_tso_win_divisor) + return left < tp->snd_cwnd / sysctl_tcp_tso_win_divisor; + else + return left <= tcp_max_burst(tp); +} + /* Check that window update is acceptable. * The function assumes that snd_una<=ack<=snd_next. */ @@ -2360,12 +2377,13 @@ static int tcp_ack(struct sock *sk, stru if (tcp_ack_is_dubious(sk, flag)) { /* Advanve CWND, if state allows this. */ - if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(sk, flag)) - tcp_cong_avoid(sk, ack, seq_rtt, prior_in_flight, 0); + if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(sk, flag) + && tcp_cwnd_full(tp, prior_in_flight, ack)) + tcp_cong_avoid(sk, ack, seq_rtt, 0); tcp_fastretrans_alert(sk, prior_snd_una, prior_packets, flag); } else { - if ((flag & FLAG_DATA_ACKED)) - tcp_cong_avoid(sk, ack, seq_rtt, prior_in_flight, 1); + if ((flag & FLAG_DATA_ACKED) && tcp_cwnd_full(tp, prior_in_flight, ack)) + tcp_cong_avoid(sk, ack, seq_rtt, 1); } -- Stephen Hemminger <[EMAIL PROTECTED]> OSDL http://developer.osdl.org/~shemminger - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html