From: "Ilpo Järvinen" <ilpo.jarvinen@helsinki.fi>
To: "Damon L. Chesser" <damon@damtek.com>
Cc: Netdev <netdev@vger.kernel.org>, David Miller <davem@davemloft.net>
Subject: Re: Fix FRTO+NewReno problem (Was: Re: This has a work around)
Date: Mon, 12 May 2008 15:07:45 +0300 (EEST) [thread overview]
Message-ID: <Pine.LNX.4.64.0805121503280.1888@wrl-59.cs.helsinki.fi> (raw)
In-Reply-To: <4828304F.4040908@damtek.com>
[-- Attachment #1: Type: text/plain, Size: 770 bytes --]
On Mon, 12 May 2008, Damon L. Chesser wrote:
> I ran the first patch and received this error:
>
> root@dam-main:/usr/src/linux-2.6.24.1# patch -p1 < ../1st_frto_patch.diff
> patching file net/ipv4/tcp_input.c
> patch: **** malformed patch at line 17: @@ -1685,6 +1683,10 @@ static inline
> void tcp_reset_reno_sack(struct tcp_sock *tp)
>
> root@dam-main:/usr/src/linux-2.6.24.1#
>
> below is the text of the patch.diff I have:
I suppose there was some space-vs-tab or additional-line-break added
issue while you saved it. Please try to save from the attached files
instead, it should keep the original formatting, they work as is with
patch -p1 (no need to cut anything). I tried them into 2.6.24.1 and both
of those should apply, though with some fuzz.
--
i.
[-- Attachment #2: Type: text/plain, Size: 4420 bytes --]
From 7f16a60972abdfa0ff8fe9bfb677aab92b714308 Mon Sep 17 00:00:00 2001
From: =?ISO-8859-1?q?Ilpo=20J=E4rvinen?= <ijjarvin@pointhope.localnet.net>
Date: Wed, 7 May 2008 21:36:42 +0300
Subject: [PATCH] [TCP] FRTO: SACK variant is errorneously used with NewReno
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
Note: there's actually another bug in FRTO's SACK variant, which
is the causing failure in NewReno case because of the error
that's fixed here. I'll fix the SACK case separately (it's
a separate bug really, though related, but in order to fix that
I need to audit tp->snd_nxt usage a bit).
There were two places where SACK variant of FRTO is getting
incorrectly used even if SACK wasn't negotiated by the TCP flow.
This leads to incorrect setting of frto_highmark with NewReno
if a previous recovery was interrupted by another RTO.
An eventual fallback to conventional recovery then incorrectly
considers one or couple of segments as forward transmissions
though they weren't, which then are not LOST marked during
fallback making them "non-retransmittable" until the next RTO.
In a bad case, those segments are really lost and are the only
one left in the window. Thus TCP needs another RTO to continue.
The next FRTO, however, could again repeat the same events
making the progress of the TCP flow extremely slow.
In order for these events to occur at all, FRTO must occur
again in FRTOs step 3 while the key segments must be lost as
well, which is not too likely in practice. It seems to most
frequently with some small devices such as network printers
that *seem* to accept TCP segments only in-order. In cases
were key segments weren't lost, things get automatically
resolved because those wrongly marked segments don't need to be
retransmitted in order to continue.
I found a reproducer after digging up relevant reports (few
reports in total, none at netdev or lkml I know of), some
cases seemed to indicate middlebox issues which seems now
to be a false assumption some people had made. Bugzilla
#10063 _might_ be related. Damon L. Chesser <damon@damtek.com>
had a reproducable case and was kind enough to tcpdump it
for me. With the tcpdump log it was quite trivial to figure
out.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
net/ipv4/tcp_input.c | 13 ++++++++-----
1 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0298f80..81ece1f 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -113,8 +113,6 @@ int sysctl_tcp_abc __read_mostly;
#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED)
#define FLAG_ANY_PROGRESS (FLAG_FORWARD_PROGRESS|FLAG_SND_UNA_ADVANCED)
-#define IsSackFrto() (sysctl_tcp_frto == 0x2)
-
#define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH)
#define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))
@@ -1685,6 +1683,11 @@ static inline void tcp_reset_reno_sack(struct tcp_sock *tp)
tp->sacked_out = 0;
}
+static int tcp_is_sackfrto(const struct tcp_sock *tp)
+{
+ return (sysctl_tcp_frto == 0x2) && !tcp_is_reno(tp);
+}
+
/* F-RTO can only be used if TCP has never retransmitted anything other than
* head (SACK enhanced variant from Appendix B of RFC4138 is more robust here)
*/
@@ -1701,7 +1704,7 @@ int tcp_use_frto(struct sock *sk)
if (icsk->icsk_mtup.probe_size)
return 0;
- if (IsSackFrto())
+ if (tcp_is_sackfrto(tp))
return 1;
/* Avoid expensive walking of rexmit queue if possible */
@@ -1791,7 +1794,7 @@ void tcp_enter_frto(struct sock *sk)
/* Earlier loss recovery underway (see RFC4138; Appendix B).
* The last condition is necessary at least in tp->frto_counter case.
*/
- if (IsSackFrto() && (tp->frto_counter ||
+ if (tcp_is_sackfrto(tp) && (tp->frto_counter ||
((1 << icsk->icsk_ca_state) & (TCPF_CA_Recovery|TCPF_CA_Loss))) &&
after(tp->high_seq, tp->snd_una)) {
tp->frto_highmark = tp->high_seq;
@@ -3123,7 +3126,7 @@ static int tcp_process_frto(struct sock *sk, int flag)
return 1;
}
- if (!IsSackFrto() || tcp_is_reno(tp)) {
+ if (!tcp_is_sackfrto(tp)) {
/* RFC4138 shortcoming in step 2; should also have case c):
* ACK isn't duplicate nor advances window, e.g., opposite dir
* data, winupdate
--
1.5.2.2
[-- Attachment #3: Type: text/plain, Size: 2027 bytes --]
From 580ddf96a4c3abf05feb6836c5a66026476ce88d Mon Sep 17 00:00:00 2001
From: =?ISO-8859-1?q?Ilpo=20J=E4rvinen?= <ilpo.jarvinen@helsinki.fi>
Date: Sun, 11 May 2008 22:50:13 +0300
Subject: [PATCH] [TCP] FRTO: Fix fallback to conventional recovery
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
It seems that commit 009a2e3e4ec ("[TCP] FRTO: Improve
interoperability with other undo_marker users") run into
another land-mine which caused fallback to conventional
recovery to break:
1. Cumulative ACK arrives after FRTO retransmission
2. tcp_try_to_open sees zero retrans_out, clears retrans_stamp
which should be kept like in CA_Loss state it would be
3. undo_marker change allowed tcp_packet_delayed to return
true because of the cleared retrans_stamp once FRTO is
terminated causing LossUndo to occur, which means all loss
markings FRTO made are reverted.
This means that the conventional recovery basically recovered
one loss per RTT, which is not that efficient. It was quite
unobvious that the undo_marker change broken something like
this, I had a quite long session to track it down because of
the non-intuitiviness of the bug (luckily I had a trivial
reproducer at hand and I was also able to learn to use kprobes
in the process as well :-)).
This together with the NewReno+FRTO fix should finally fix
Damon's problems.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Reported-by: Damon L. Chesser <damon@damtek.com>
---
net/ipv4/tcp_input.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 81ece1f..4c2255c 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2481,7 +2481,7 @@ static void tcp_try_to_open(struct sock *sk, int flag)
tcp_verify_left_out(tp);
- if (tp->retrans_out == 0)
+ if (!tp->frto_counter && tp->retrans_out == 0)
tp->retrans_stamp = 0;
if (flag & FLAG_ECE)
--
1.5.2.2
next prev parent reply other threads:[~2008-05-12 12:07 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <48207F06.50306@damtek.com>
[not found] ` <Pine.LNX.4.64.0805061912350.8965@wrl-59.cs.helsinki.fi>
[not found] ` <4821C37A.7040306@damtek.com>
2008-05-07 22:26 ` Fix FRTO+NewReno problem (Was: Re: This has a work around) Ilpo Järvinen
2008-05-08 8:10 ` Fix FRTO+NewReno problem David Miller
2008-05-08 16:50 ` Bug#478062: Fix FRTO+NewReno problem (Was: Re: This has a work around) Damon L. Chesser
2008-05-08 17:05 ` Damon L. Chesser
2008-05-08 18:16 ` Damon L. Chesser
2008-05-08 20:42 ` Ilpo Järvinen
2008-05-12 10:08 ` Ilpo Järvinen
[not found] ` <4828279C.3010102@damtek.com>
2008-05-12 11:32 ` Ilpo Järvinen
2008-05-12 11:55 ` Damon L. Chesser
2008-05-12 12:07 ` Ilpo Järvinen [this message]
2008-05-12 13:44 ` Damon L. Chesser
2008-05-12 14:35 ` Ilpo Järvinen
2008-05-12 16:40 ` Ilpo Järvinen
2008-05-12 17:02 ` Damon L. Chesser
2008-05-12 18:23 ` Ilpo Järvinen
2008-05-12 18:39 ` Damon L. Chesser
2008-05-12 19:12 ` Ilpo Järvinen
2008-05-12 19:18 ` Damon L. Chesser
2008-05-12 19:25 ` Ilpo Järvinen
2008-05-12 22:48 ` Fix FRTO+NewReno problem David Miller
2008-05-13 9:42 ` Ilpo Järvinen
2008-05-13 9:49 ` David Miller
2008-05-13 10:04 ` Ilpo Järvinen
2008-05-13 10:08 ` David Miller
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=Pine.LNX.4.64.0805121503280.1888@wrl-59.cs.helsinki.fi \
--to=ilpo.jarvinen@helsinki.fi \
--cc=damon@damtek.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
/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;
as well as URLs for NNTP newsgroup(s).