|
@@ -99,6 +99,7 @@ int sysctl_tcp_thin_dupack __read_mostly;
|
|
|
|
|
|
int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
|
|
|
int sysctl_tcp_abc __read_mostly;
|
|
|
+int sysctl_tcp_early_retrans __read_mostly = 2;
|
|
|
|
|
|
#define FLAG_DATA 0x01 /* Incoming frame contained data. */
|
|
|
#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */
|
|
@@ -906,6 +907,7 @@ static void tcp_init_metrics(struct sock *sk)
|
|
|
if (dst_metric(dst, RTAX_REORDERING) &&
|
|
|
tp->reordering != dst_metric(dst, RTAX_REORDERING)) {
|
|
|
tcp_disable_fack(tp);
|
|
|
+ tcp_disable_early_retrans(tp);
|
|
|
tp->reordering = dst_metric(dst, RTAX_REORDERING);
|
|
|
}
|
|
|
|
|
@@ -988,6 +990,9 @@ static void tcp_update_reordering(struct sock *sk, const int metric,
|
|
|
#endif
|
|
|
tcp_disable_fack(tp);
|
|
|
}
|
|
|
+
|
|
|
+ if (metric > 0)
|
|
|
+ tcp_disable_early_retrans(tp);
|
|
|
}
|
|
|
|
|
|
/* This must be called before lost_out is incremented */
|
|
@@ -2492,6 +2497,16 @@ static int tcp_time_to_recover(struct sock *sk)
|
|
|
tcp_is_sack(tp) && !tcp_send_head(sk))
|
|
|
return 1;
|
|
|
|
|
|
+ /* Trick#6: TCP early retransmit, per RFC5827. To avoid spurious
|
|
|
+ * retransmissions due to small network reorderings, we implement
|
|
|
+ * Mitigation A.3 in the RFC and delay the retransmission for a short
|
|
|
+ * interval if appropriate.
|
|
|
+ */
|
|
|
+ if (tp->do_early_retrans && !tp->retrans_out && tp->sacked_out &&
|
|
|
+ (tp->packets_out == (tp->sacked_out + 1) && tp->packets_out < 4) &&
|
|
|
+ !tcp_may_send_now(sk))
|
|
|
+ return 1;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|