|
@@ -2485,8 +2485,6 @@ static void tcp_try_to_open(struct sock *sk, int flag, const int prior_unsacked)
|
|
|
|
|
|
if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) {
|
|
|
tcp_try_keep_open(sk);
|
|
|
- if (inet_csk(sk)->icsk_ca_state != TCP_CA_Open)
|
|
|
- tcp_moderate_cwnd(tp);
|
|
|
} else {
|
|
|
tcp_cwnd_reduction(sk, prior_unsacked, 0);
|
|
|
}
|
|
@@ -3128,11 +3126,24 @@ static inline bool tcp_ack_is_dubious(const struct sock *sk, const int flag)
|
|
|
inet_csk(sk)->icsk_ca_state != TCP_CA_Open;
|
|
|
}
|
|
|
|
|
|
+/* Decide wheather to run the increase function of congestion control. */
|
|
|
static inline bool tcp_may_raise_cwnd(const struct sock *sk, const int flag)
|
|
|
{
|
|
|
- const struct tcp_sock *tp = tcp_sk(sk);
|
|
|
- return (!(flag & FLAG_ECE) || tp->snd_cwnd < tp->snd_ssthresh) &&
|
|
|
- !tcp_in_cwnd_reduction(sk);
|
|
|
+ if (tcp_in_cwnd_reduction(sk))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ /* If reordering is high then always grow cwnd whenever data is
|
|
|
+ * delivered regardless of its ordering. Otherwise stay conservative
|
|
|
+ * and only grow cwnd on in-order delivery in Open state, and retain
|
|
|
+ * cwnd in Disordered state (RFC5681). A stretched ACK with
|
|
|
+ * new SACK or ECE mark may first advance cwnd here and later reduce
|
|
|
+ * cwnd in tcp_fastretrans_alert() based on more states.
|
|
|
+ */
|
|
|
+ if (tcp_sk(sk)->reordering > sysctl_tcp_reordering)
|
|
|
+ return flag & FLAG_FORWARD_PROGRESS;
|
|
|
+
|
|
|
+ return inet_csk(sk)->icsk_ca_state == TCP_CA_Open &&
|
|
|
+ flag & FLAG_DATA_ACKED;
|
|
|
}
|
|
|
|
|
|
/* Check that window update is acceptable.
|
|
@@ -3352,18 +3363,15 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
|
|
|
flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, sack_rtt);
|
|
|
acked -= tp->packets_out;
|
|
|
|
|
|
+ /* Advance cwnd if state allows */
|
|
|
+ if (tcp_may_raise_cwnd(sk, flag))
|
|
|
+ tcp_cong_avoid(sk, ack, prior_in_flight);
|
|
|
+
|
|
|
if (tcp_ack_is_dubious(sk, flag)) {
|
|
|
- /* Advance CWND, if state allows this. */
|
|
|
- if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(sk, flag))
|
|
|
- tcp_cong_avoid(sk, ack, prior_in_flight);
|
|
|
is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
|
|
|
tcp_fastretrans_alert(sk, acked, prior_unsacked,
|
|
|
is_dupack, flag);
|
|
|
- } else {
|
|
|
- if (flag & FLAG_DATA_ACKED)
|
|
|
- tcp_cong_avoid(sk, ack, prior_in_flight);
|
|
|
}
|
|
|
-
|
|
|
if (tp->tlp_high_seq)
|
|
|
tcp_process_tlp_ack(sk, ack, flag);
|
|
|
|