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

Reply via email to