From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Yuchung Cheng <ycheng@google.com>,
Neal Cardwell <ncardwell@google.com>,
"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 3.4 08/23] tcp: fix false undo corner cases
Date: Sat, 26 Jul 2014 12:02:08 -0700 [thread overview]
Message-ID: <20140726190149.980682948@linuxfoundation.org> (raw)
In-Reply-To: <20140726190149.723570428@linuxfoundation.org>
3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuchung Cheng <ycheng@google.com>
[ Upstream commit 6e08d5e3c8236e7484229e46fdf92006e1dd4c49 ]
The undo code assumes that, upon entering loss recovery, TCP
1) always retransmit something
2) the retransmission never fails locally (e.g., qdisc drop)
so undo_marker is set in tcp_enter_recovery() and undo_retrans is
incremented only when tcp_retransmit_skb() is successful.
When the assumption is broken because TCP's cwnd is too small to
retransmit or the retransmit fails locally. The next (DUP)ACK
would incorrectly revert the cwnd and the congestion state in
tcp_try_undo_dsack() or tcp_may_undo(). Subsequent (DUP)ACKs
may enter the recovery state. The sender repeatedly enter and
(incorrectly) exit recovery states if the retransmits continue to
fail locally while receiving (DUP)ACKs.
The fix is to initialize undo_retrans to -1 and start counting on
the first retransmission. Always increment undo_retrans even if the
retransmissions fail locally because they couldn't cause DSACKs to
undo the cwnd reduction.
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/tcp_input.c | 8 ++++----
net/ipv4/tcp_output.c | 6 ++++--
2 files changed, 8 insertions(+), 6 deletions(-)
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1250,7 +1250,7 @@ static int tcp_check_dsack(struct sock *
}
/* D-SACK for already forgotten data... Do dumb counting. */
- if (dup_sack && tp->undo_marker && tp->undo_retrans &&
+ if (dup_sack && tp->undo_marker && tp->undo_retrans > 0 &&
!after(end_seq_0, prior_snd_una) &&
after(end_seq_0, tp->undo_marker))
tp->undo_retrans--;
@@ -1328,7 +1328,7 @@ static u8 tcp_sacktag_one(struct sock *s
/* Account D-SACK for retransmitted packet. */
if (dup_sack && (sacked & TCPCB_RETRANS)) {
- if (tp->undo_marker && tp->undo_retrans &&
+ if (tp->undo_marker && tp->undo_retrans > 0 &&
after(end_seq, tp->undo_marker))
tp->undo_retrans--;
if (sacked & TCPCB_SACKED_ACKED)
@@ -2226,7 +2226,7 @@ static void tcp_clear_retrans_partial(st
tp->lost_out = 0;
tp->undo_marker = 0;
- tp->undo_retrans = 0;
+ tp->undo_retrans = -1;
}
void tcp_clear_retrans(struct tcp_sock *tp)
@@ -3165,7 +3165,7 @@ static void tcp_fastretrans_alert(struct
tp->high_seq = tp->snd_nxt;
tp->prior_ssthresh = 0;
tp->undo_marker = tp->snd_una;
- tp->undo_retrans = tp->retrans_out;
+ tp->undo_retrans = tp->retrans_out ? : -1;
if (icsk->icsk_ca_state < TCP_CA_CWR) {
if (!(flag & FLAG_ECE))
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2194,13 +2194,15 @@ int tcp_retransmit_skb(struct sock *sk,
if (!tp->retrans_stamp)
tp->retrans_stamp = TCP_SKB_CB(skb)->when;
- tp->undo_retrans += tcp_skb_pcount(skb);
-
/* snd_nxt is stored to detect loss of retransmitted segment,
* see tcp_input.c tcp_sacktag_write_queue().
*/
TCP_SKB_CB(skb)->ack_seq = tp->snd_nxt;
}
+
+ if (tp->undo_retrans < 0)
+ tp->undo_retrans = 0;
+ tp->undo_retrans += tcp_skb_pcount(skb);
return err;
}
next prev parent reply other threads:[~2014-07-26 20:17 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-26 19:02 [PATCH 3.4 00/23] 3.4.100-stable review Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 01/23] crypto: testmgr - update LZO compression test vectors Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 02/23] shmem: fix faulting into a hole while its punched Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 03/23] shmem: fix faulting into a hole, not taking i_mutex Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 04/23] shmem: fix splicing from a hole while its punched Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 05/23] tcp: fix tcp_match_skb_to_sack() for unaligned SACK at end of an skb Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 06/23] 8021q: fix a potential memory leak Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 07/23] igmp: fix the problem when mc leave group Greg Kroah-Hartman
2014-07-26 19:02 ` Greg Kroah-Hartman [this message]
2014-07-26 19:02 ` [PATCH 3.4 09/23] appletalk: Fix socket referencing in skb Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 10/23] be2net: set EQ DB clear-intr bit in be_open() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 11/23] tipc: clear next-pointer of message fragments before reassembly Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 12/23] net: sctp: fix information leaks in ulpevent layer Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 13/23] net: pppoe: use correct channel MTU when using Multilink PPP Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 14/23] sunvnet: clean up objects created in vnet_new() on vnet_exit() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 16/23] dns_resolver: Null-terminate the right string Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 17/23] ipv4: fix buffer overflow in ip_options_compile() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 19/23] mwifiex: fix Tx timeout issue Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 20/23] drm/radeon: avoid leaking edid data Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 21/23] alarmtimer: Fix bug where relative alarm timers were treated as absolute Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 22/23] PM / sleep: Fix request_firmware() error at resume Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.4 23/23] iommu/vt-d: Disable translation if already enabled Greg Kroah-Hartman
2014-07-27 14:58 ` [PATCH 3.4 00/23] 3.4.100-stable review Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140726190149.980682948@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=ncardwell@google.com \
--cc=stable@vger.kernel.org \
--cc=ycheng@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox