aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-03-02 16:34:19 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:23:26 -0400
commite317f6f69cb95527799d308a9421b7dc1252989a (patch)
tree141ff608a450f1d768383f300cc204db5904b20c
parente01f9d7793be82e6c252efbd52c399d3eb65abe4 (diff)
[TCP]: FRTO undo response falls back to ratehalving one if ECEd
Undoing ssthresh is disabled in fastretrans_alert whenever FLAG_ECE is set by clearing prior_ssthresh. The clearing does not protect FRTO because FRTO operates before fastretrans_alert. Moving the clearing of prior_ssthresh earlier seems to be a suboptimal solution to the FRTO case because then FLAG_ECE will cause a second ssthresh reduction in try_to_open (the first occurred when FRTO was entered). So instead, FRTO falls back immediately to the rate halving response, which switches TCP to CA_CWR state preventing the latter reduction of ssthresh. If the first ECE arrived before the ACK after which FRTO is able to decide RTO as spurious, prior_ssthresh is already cleared. Thus no undoing for ssthresh occurs. Besides, FLAG_ECE should be set also in the following ACKs resulting in rate halving response that sees TCP is already in CA_CWR, which again prevents an extra ssthresh reduction on that round-trip. If the first ECE arrived before RTO, ssthresh has already been adapted and prior_ssthresh remains cleared on entry because TCP is in CA_CWR (the same applies also to a case where FRTO is entered more than once and ECE comes in the middle). High_seq must not be touched after tcp_enter_cwr because CWR round-trip calculation depends on it. I believe that after this patch, FRTO should be ECN-safe and even able to take advantage of synergy benefits. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/tcp_input.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index cb715eadf8f5..d894bbcc1d24 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2587,14 +2587,15 @@ static void tcp_conservative_spur_to_response(struct tcp_sock *tp)
2587 */ 2587 */
2588static void tcp_ratehalving_spur_to_response(struct sock *sk) 2588static void tcp_ratehalving_spur_to_response(struct sock *sk)
2589{ 2589{
2590 struct tcp_sock *tp = tcp_sk(sk);
2591 tcp_enter_cwr(sk, 0); 2590 tcp_enter_cwr(sk, 0);
2592 tp->high_seq = tp->frto_highmark; /* Smoother w/o this? - ij */
2593} 2591}
2594 2592
2595static void tcp_undo_spur_to_response(struct sock *sk) 2593static void tcp_undo_spur_to_response(struct sock *sk, int flag)
2596{ 2594{
2597 tcp_undo_cwr(sk, 1); 2595 if (flag&FLAG_ECE)
2596 tcp_ratehalving_spur_to_response(sk);
2597 else
2598 tcp_undo_cwr(sk, 1);
2598} 2599}
2599 2600
2600/* F-RTO spurious RTO detection algorithm (RFC4138) 2601/* F-RTO spurious RTO detection algorithm (RFC4138)
@@ -2681,7 +2682,7 @@ static int tcp_process_frto(struct sock *sk, u32 prior_snd_una, int flag)
2681 } else /* frto_counter == 2 */ { 2682 } else /* frto_counter == 2 */ {
2682 switch (sysctl_tcp_frto_response) { 2683 switch (sysctl_tcp_frto_response) {
2683 case 2: 2684 case 2:
2684 tcp_undo_spur_to_response(sk); 2685 tcp_undo_spur_to_response(sk, flag);
2685 break; 2686 break;
2686 case 1: 2687 case 1:
2687 tcp_conservative_spur_to_response(tp); 2688 tcp_conservative_spur_to_response(tp);