From: Eric Dumazet <hidden> Date: 2012-07-20 15:02:39
From: Eric Dumazet <edumazet@google.com>
When/if sysctl_tcp_abc > 1, we expect to increase cwnd by 2 if the
received ACK acknowledges more than 2*MSS bytes, in tcp_slow_start()
Problem is this RFC 3465 statement is not correctly coded, as
the while () loop increases snd_cwnd one by one.
Add a new variable to avoid this off-by one error.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Tom Herbert <redacted>
Cc: Yuchung Cheng <redacted>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Nandita Dukkipati <redacted>
Cc: John Heffner <redacted>
Cc: Stephen Hemminger <redacted>
---
v2: added John suggestion
net/ipv4/tcp_cong.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
On Fri, Jul 20, 2012 at 8:02 AM, Eric Dumazet [off-list ref] wrote:
From: Eric Dumazet <edumazet@google.com>
When/if sysctl_tcp_abc > 1, we expect to increase cwnd by 2 if the
received ACK acknowledges more than 2*MSS bytes, in tcp_slow_start()
Problem is this RFC 3465 statement is not correctly coded, as
the while () loop increases snd_cwnd one by one.
Add a new variable to avoid this off-by one error.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Yuchung Cheng <redacted>
quoted hunk
Cc: Tom Herbert <redacted>
Cc: Yuchung Cheng <redacted>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Nandita Dukkipati <redacted>
Cc: John Heffner <redacted>
Cc: Stephen Hemminger <redacted>
---
v2: added John suggestion
net/ipv4/tcp_cong.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
On Fri, Jul 20, 2012 at 8:07 AM, Yuchung Cheng [off-list ref] wrote:
On Fri, Jul 20, 2012 at 8:02 AM, Eric Dumazet [off-list ref] wrote:
quoted
tp->snd_cwnd_cnt += cnt;
while (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
Nice catch, Eric.
One thing that's always bothered me about the tp->snd_cwnd_cnt code is
that the slow start and congestion avoidance use different criteria
for incrementing snd_cwnd_cnt. tcp_slow_start() increments
snd_cwnd_cnt by snd_cwnd for each ACKed packet, and congestion
avoidance increases snd_cwnd_cnt by just 1 for each packet.
This means that if we exit slow start and enter congestion avoidance,
then we think we can have a "credit" for a bunch of ACKs that never
happened (up to snd_cwnd-1), so we can conceivably do our first
additive increase in congestion avoidance up to almost 1RTT too
early. Can we just get rid of the use of snd_cwnd_cnt in slow start,
and just use local variables in tcp_slow_start() rather than trying to
carry state between ACKs?
neal
From: Eric Dumazet <hidden> Date: 2012-07-20 16:09:01
On Fri, 2012-07-20 at 09:03 -0700, Neal Cardwell wrote:
On Fri, Jul 20, 2012 at 8:07 AM, Yuchung Cheng [off-list ref] wrote:
quoted
On Fri, Jul 20, 2012 at 8:02 AM, Eric Dumazet [off-list ref] wrote:
quoted
tp->snd_cwnd_cnt += cnt;
while (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
Nice catch, Eric.
One thing that's always bothered me about the tp->snd_cwnd_cnt code is
that the slow start and congestion avoidance use different criteria
for incrementing snd_cwnd_cnt. tcp_slow_start() increments
snd_cwnd_cnt by snd_cwnd for each ACKed packet, and congestion
avoidance increases snd_cwnd_cnt by just 1 for each packet.
This means that if we exit slow start and enter congestion avoidance,
then we think we can have a "credit" for a bunch of ACKs that never
happened (up to snd_cwnd-1), so we can conceivably do our first
additive increase in congestion avoidance up to almost 1RTT too
early. Can we just get rid of the use of snd_cwnd_cnt in slow start,
and just use local variables in tcp_slow_start() rather than trying to
carry state between ACKs?
Apparently tcp_slow_start() needs the snd_cwnd_cnt in case
"limited slow start" is used :
cnt = sysctl_tcp_max_ssthresh >> 1;
So to address your point, maybe we should clear snd_cwnd_cnt
when leaving slow start for congestion avoidance phase ?
On Fri, Jul 20, 2012 at 9:08 AM, Eric Dumazet [off-list ref] wrote:
So to address your point, maybe we should clear snd_cwnd_cnt
when leaving slow start for congestion avoidance phase ?
Sounds good. That can be a separate commit to add the new logic to the
end of tcp_slow_start() to check to see if we've bumped into ssthresh
and reset snd_cwnd_cnt.
neal
On Fri, Jul 20, 2012 at 8:07 AM, Yuchung Cheng [off-list ref] wrote:
On Fri, Jul 20, 2012 at 8:02 AM, Eric Dumazet [off-list ref] wrote:
quoted
From: Eric Dumazet <edumazet@google.com>
When/if sysctl_tcp_abc > 1, we expect to increase cwnd by 2 if the
received ACK acknowledges more than 2*MSS bytes, in tcp_slow_start()
Problem is this RFC 3465 statement is not correctly coded, as
the while () loop increases snd_cwnd one by one.
Add a new variable to avoid this off-by one error.
Signed-off-by: Eric Dumazet <edumazet@google.com>
On Fri, Jul 20, 2012 at 8:07 AM, Yuchung Cheng [off-list ref] wrote:
quoted
On Fri, Jul 20, 2012 at 8:02 AM, Eric Dumazet [off-list ref] wrote:
quoted
From: Eric Dumazet <edumazet@google.com>
When/if sysctl_tcp_abc > 1, we expect to increase cwnd by 2 if the
received ACK acknowledges more than 2*MSS bytes, in tcp_slow_start()
Problem is this RFC 3465 statement is not correctly coded, as
the while () loop increases snd_cwnd one by one.
Add a new variable to avoid this off-by one error.
Signed-off-by: Eric Dumazet <edumazet@google.com>