From 12de798c3944928ed8dae9e5dba774deb3305583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Mon, 7 Apr 2008 22:33:07 -0700 Subject: [PATCH] --- yaml --- r: 88255 b: refs/heads/master c: 882bebaaca4bb1484078d44ef011f918c0e1e14e h: refs/heads/master i: 88253: 72acfa36e9c4ac01dea9a9f430a09869a1d236df 88251: a11c6c68a8f53b4e2d5cfcbc303bab7b19e0af2b 88247: 208c7a52d8a1f4b43bd7c5be2a8cd6e633a64040 88239: 74ee94e2e5bd90fa90a45baf2e1e5393add90f64 88223: 4e3fc94c0fbcde0d319e21dbbc3f0f1a72ca7671 88191: 4dc3125d74f3dfb5af7f365fbcb4cc5d50148ed7 v: v3 --- [refs] | 2 +- trunk/include/net/tcp.h | 2 ++ trunk/net/ipv4/tcp_input.c | 24 ++++++++++++++++++------ trunk/net/ipv4/tcp_output.c | 3 +++ 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 5f9f9536f332..1d5ea682ac12 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c137f3dda04b0aee1bc6889cdc69185f53df8a82 +refs/heads/master: 882bebaaca4bb1484078d44ef011f918c0e1e14e diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index 7de4ea3a04d9..4fd3eb2f8ec2 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -752,6 +752,8 @@ static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp) return tp->packets_out - tcp_left_out(tp) + tp->retrans_out; } +extern int tcp_limit_reno_sacked(struct tcp_sock *tp); + /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd. * The exception is rate halving phase, when cwnd is decreasing towards * ssthresh. diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 7d0958785bfb..b4812c3cbbcf 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -1625,13 +1625,11 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, return flag; } -/* If we receive more dupacks than we expected counting segments - * in assumption of absent reordering, interpret this as reordering. - * The only another reason could be bug in receiver TCP. +/* Limits sacked_out so that sum with lost_out isn't ever larger than + * packets_out. Returns zero if sacked_out adjustement wasn't necessary. */ -static void tcp_check_reno_reordering(struct sock *sk, const int addend) +int tcp_limit_reno_sacked(struct tcp_sock *tp) { - struct tcp_sock *tp = tcp_sk(sk); u32 holes; holes = max(tp->lost_out, 1U); @@ -1639,8 +1637,20 @@ static void tcp_check_reno_reordering(struct sock *sk, const int addend) if ((tp->sacked_out + holes) > tp->packets_out) { tp->sacked_out = tp->packets_out - holes; - tcp_update_reordering(sk, tp->packets_out + addend, 0); + return 1; } + return 0; +} + +/* If we receive more dupacks than we expected counting segments + * in assumption of absent reordering, interpret this as reordering. + * The only another reason could be bug in receiver TCP. + */ +static void tcp_check_reno_reordering(struct sock *sk, const int addend) +{ + struct tcp_sock *tp = tcp_sk(sk); + if (tcp_limit_reno_sacked(tp)) + tcp_update_reordering(sk, tp->packets_out + addend, 0); } /* Emulate SACKs for SACKless connection: account for a new dupack. */ @@ -2600,6 +2610,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) case TCP_CA_Loss: if (flag & FLAG_DATA_ACKED) icsk->icsk_retransmits = 0; + if (tcp_is_reno(tp) && flag & FLAG_SND_UNA_ADVANCED) + tcp_reset_reno_sack(tp); if (!tcp_try_undo_loss(sk)) { tcp_moderate_cwnd(tp); tcp_xmit_retransmit_queue(sk); diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 72b9350006fe..d29ef79c00ca 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -1808,6 +1808,9 @@ void tcp_simple_retransmit(struct sock *sk) if (!lost) return; + if (tcp_is_reno(tp)) + tcp_limit_reno_sacked(tp); + tcp_verify_left_out(tp); /* Don't muck with the congestion window here.