netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Why is tcp_reno_min_cwnd() ssthresh/2?
@ 2008-04-04  1:00 Lachlan Andrew
  2008-04-04  2:35 ` Xiaoliang "David" Wei
  0 siblings, 1 reply; 5+ messages in thread
From: Lachlan Andrew @ 2008-04-04  1:00 UTC (permalink / raw)
  To: Netdev

Greetings all,

Apologies if this is a dumb question, but why does
tcp_reno_min_cwnd()  return  ssthresh/2?

Since   ssthresh <- snd_cwnd/2   on loss, this looks like it tries to
reduce  snd_cwnd  to 1/4 its value before a loss event, presumably
then slow-starting back to half of the original  snd_cwnd.

As Tom Quetchenbach pointed out, it is also odd that  omitting
min_cwnd()  from a congestion control module causes  ssthresh  to be
used, giving different results from using  tcp_reno_min_cwnd().

Thanks,
Lachlan

-- 
Lachlan Andrew  Dept of Computer Science, Caltech
1200 E California Blvd, Mail Code 256-80, Pasadena CA 91125, USA
Ph: +1 (626) 395-8820    Fax: +1 (626) 568-3603
http://netlab.caltech.edu/lachlan

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Why is tcp_reno_min_cwnd() ssthresh/2?
  2008-04-04  1:00 Why is tcp_reno_min_cwnd() ssthresh/2? Lachlan Andrew
@ 2008-04-04  2:35 ` Xiaoliang "David" Wei
  2008-04-04 16:24   ` John Heffner
  0 siblings, 1 reply; 5+ messages in thread
From: Xiaoliang "David" Wei @ 2008-04-04  2:35 UTC (permalink / raw)
  To: Lachlan Andrew; +Cc: Netdev

Hi Lachlan,

    I think the reno_min_cwnd gives a lower bound of the cwnd during
one round of rate halving. So it is not *always* that cwnd will go to
reno_min_cwnd. If the recovery is done before the cwnd dropping to
reno_min_cwnd, the cwnd will be drop by at least one half. I think the
assumption is that normally one round of rate-halving will end up with
a half of congestion window so this lower bound is not activated.

    The last time I examined this algorithm, I got the following
document about rate halving:
http://www.psc.edu/networking/papers/FACKnotes/current/

    (It might be possible that the assumptions in this draft might be
out-dated or I misunderstood the algorithms :)

-David

On Thu, Apr 3, 2008 at 6:00 PM, Lachlan Andrew <lachlan.andrew@gmail.com> wrote:
> Greetings all,
>
>  Apologies if this is a dumb question, but why does
>  tcp_reno_min_cwnd()  return  ssthresh/2?
>
>  Since   ssthresh <- snd_cwnd/2   on loss, this looks like it tries to
>  reduce  snd_cwnd  to 1/4 its value before a loss event, presumably
>  then slow-starting back to half of the original  snd_cwnd.
>
>  As Tom Quetchenbach pointed out, it is also odd that  omitting
>  min_cwnd()  from a congestion control module causes  ssthresh  to be
>  used, giving different results from using  tcp_reno_min_cwnd().
>
>  Thanks,
>  Lachlan
>
>  --
>  Lachlan Andrew  Dept of Computer Science, Caltech
>  1200 E California Blvd, Mail Code 256-80, Pasadena CA 91125, USA
>  Ph: +1 (626) 395-8820    Fax: +1 (626) 568-3603
>  http://netlab.caltech.edu/lachlan
>  --
>  To unsubscribe from this list: send the line "unsubscribe netdev" in
>  the body of a message to majordomo@vger.kernel.org
>  More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Xiaoliang "David" Wei
http://davidwei.org
***********************************************

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Why is tcp_reno_min_cwnd() ssthresh/2?
  2008-04-04  2:35 ` Xiaoliang "David" Wei
@ 2008-04-04 16:24   ` John Heffner
  2008-04-04 18:31     ` Stephen Hemminger
  0 siblings, 1 reply; 5+ messages in thread
From: John Heffner @ 2008-04-04 16:24 UTC (permalink / raw)
  To: Xiaoliang David Wei; +Cc: Lachlan Andrew, Netdev

That's my understanding as well.  I'm pretty sure this has come up on
the list before, more than once.  Someone should probably add a
comment there.

Also, I'm pretty sure no one has a strong opinion that this bound must
be cwnd/4.  In fact it is known to behave poorly in some situations.
An argument for a different value or approach may be well received.

  -John


On Thu, Apr 3, 2008 at 7:35 PM, Xiaoliang David Wei
<davidwei79@gmail.com> wrote:
> Hi Lachlan,
>
>     I think the reno_min_cwnd gives a lower bound of the cwnd during
>  one round of rate halving. So it is not *always* that cwnd will go to
>  reno_min_cwnd. If the recovery is done before the cwnd dropping to
>  reno_min_cwnd, the cwnd will be drop by at least one half. I think the
>  assumption is that normally one round of rate-halving will end up with
>  a half of congestion window so this lower bound is not activated.
>
>     The last time I examined this algorithm, I got the following
>  document about rate halving:
>  http://www.psc.edu/networking/papers/FACKnotes/current/
>
>     (It might be possible that the assumptions in this draft might be
>  out-dated or I misunderstood the algorithms :)
>
>  -David
>
>
>
>  On Thu, Apr 3, 2008 at 6:00 PM, Lachlan Andrew <lachlan.andrew@gmail.com> wrote:
>  > Greetings all,
>  >
>  >  Apologies if this is a dumb question, but why does
>  >  tcp_reno_min_cwnd()  return  ssthresh/2?
>  >
>  >  Since   ssthresh <- snd_cwnd/2   on loss, this looks like it tries to
>  >  reduce  snd_cwnd  to 1/4 its value before a loss event, presumably
>  >  then slow-starting back to half of the original  snd_cwnd.
>  >
>  >  As Tom Quetchenbach pointed out, it is also odd that  omitting
>  >  min_cwnd()  from a congestion control module causes  ssthresh  to be
>  >  used, giving different results from using  tcp_reno_min_cwnd().
>  >
>  >  Thanks,
>  >  Lachlan
>  >
>  >  --
>  >  Lachlan Andrew  Dept of Computer Science, Caltech
>  >  1200 E California Blvd, Mail Code 256-80, Pasadena CA 91125, USA
>  >  Ph: +1 (626) 395-8820    Fax: +1 (626) 568-3603
>  >  http://netlab.caltech.edu/lachlan
>  >  --
>  >  To unsubscribe from this list: send the line "unsubscribe netdev" in
>  >  the body of a message to majordomo@vger.kernel.org
>  >  More majordomo info at  http://vger.kernel.org/majordomo-info.html
>  >
>
>
>
>  --
>  Xiaoliang "David" Wei
>  http://davidwei.org
>  ***********************************************
>
>
> --
>  To unsubscribe from this list: send the line "unsubscribe netdev" in
>  the body of a message to majordomo@vger.kernel.org
>  More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Why is tcp_reno_min_cwnd() ssthresh/2?
  2008-04-04 16:24   ` John Heffner
@ 2008-04-04 18:31     ` Stephen Hemminger
  2008-04-04 19:27       ` Lachlan Andrew
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Hemminger @ 2008-04-04 18:31 UTC (permalink / raw)
  To: John Heffner, Lachlan Andrew; +Cc: Xiaoliang David Wei, Netdev

> Greetings all,
> 
> Apologies if this is a dumb question, but why does
> tcp_reno_min_cwnd()  return  ssthresh/2?
> 
> Since   ssthresh <- snd_cwnd/2   on loss, this looks like it tries to
> reduce  snd_cwnd  to 1/4 its value before a loss event, presumably
> then slow-starting back to half of the original  snd_cwnd.
> 
> As Tom Quetchenbach pointed out, it is also odd that  omitting
> min_cwnd()  from a congestion control module causes  ssthresh  to be
> used, giving different results from using  tcp_reno_min_cwnd().
> 
> Thanks,
> Lachlan

First sighed 5 years ago, and every times it comes up, the original
behaviour is retained.

http://oss.sgi.com/archives/netdev/2003-01/msg00114.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Why is tcp_reno_min_cwnd() ssthresh/2?
  2008-04-04 18:31     ` Stephen Hemminger
@ 2008-04-04 19:27       ` Lachlan Andrew
  0 siblings, 0 replies; 5+ messages in thread
From: Lachlan Andrew @ 2008-04-04 19:27 UTC (permalink / raw)
  To: Netdev

[-- Attachment #1: Type: text/plain, Size: 3218 bytes --]

Thanks Stephen and all,

I still don't understand why  tcp_cwnd_min()  doesn't default to  Reno
 behaviour.  (The only algorithms this currently affects are BIC and
CUBIC, but since CUBIC is the default, that is important.)

John is right that it would be great to have this documented in the
code.  FWIW, the attached patch points to the mailing list post, and
also makes  tcp_cwnd_min  default to Reno behaviour.  (The inline
patch below is probably mangled by my mail client.)  This patch
changes the behaviour of CUBIC.

Cheers,
Lachlan

diff -ruNp linux-2.6.25-rc7/include/net/tcp.h
linux-2.6.25-rc7-comments/include/net/tcp.h
--- linux-2.6.25-rc7/include/net/tcp.h	2008-03-27 18:25:07.000000000 -0800
+++ linux-2.6.25-rc7-comments/include/net/tcp.h	2008-04-04
11:05:39.000000000 -0800
@@ -645,7 +645,7 @@ struct tcp_congestion_ops {

 	/* return slow start threshold (required) */
 	u32 (*ssthresh)(struct sock *sk);
-	/* lower bound for congestion window (optional) */
+	/* lower bound for congestion window during rate halving (optional) */
 	u32 (*min_cwnd)(const struct sock *sk);
 	/* do new cwnd calculation (required) */
 	void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight);
diff -ruNp linux-2.6.25-rc7/net/ipv4/tcp_cong.c
linux-2.6.25-rc7-comments/net/ipv4/tcp_cong.c
--- linux-2.6.25-rc7/net/ipv4/tcp_cong.c	2008-03-27 18:25:07.000000000 -0800
+++ linux-2.6.25-rc7-comments/net/ipv4/tcp_cong.c	2008-04-04
11:05:00.000000000 -0800
@@ -387,6 +387,8 @@ u32 tcp_reno_ssthresh(struct sock *sk)
 EXPORT_SYMBOL_GPL(tcp_reno_ssthresh);

 /* Lower bound on congestion window with halving. */
+/* Allows snd_cwnd to reduce to prev_cwnd/4  */
+/*   -- see http://oss.sgi.com/archives/netdev/2003-01/msg00114.html */
 u32 tcp_reno_min_cwnd(const struct sock *sk)
 {
 	const struct tcp_sock *tp = tcp_sk(sk);
diff -ruNp linux-2.6.25-rc7/net/ipv4/tcp_input.c
linux-2.6.25-rc7-comments/net/ipv4/tcp_input.c
--- linux-2.6.25-rc7/net/ipv4/tcp_input.c	2008-03-27 18:25:07.000000000 -0800
+++ linux-2.6.25-rc7-comments/net/ipv4/tcp_input.c	2008-04-04
11:07:43.000000000 -0800
@@ -2233,14 +2233,15 @@ static inline void tcp_moderate_cwnd(str
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }

-/* Lower bound on congestion window is slow start threshold
+/* Lower bound on congestion window during rate halving is *half* of
+ * slow start threshold (see net/ipv4/tcp_cong.c:tcp_reno_min_cwnd() )
  * unless congestion avoidance choice decides to overide it.
  */
 static inline u32 tcp_cwnd_min(const struct sock *sk)
 {
 	const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;

-	return ca_ops->min_cwnd ? ca_ops->min_cwnd(sk) : tcp_sk(sk)->snd_ssthresh;
+	return ca_ops->min_cwnd ? ca_ops->min_cwnd(sk) : tcp_sk(sk)->snd_ssthresh / 2;
 }

 /* Decrease cwnd each second ack. */


On 04/04/2008, Stephen Hemminger <shemminger@vyatta.com> wrote:
>
> First sighed 5 years ago, and every times it comes up, the original
>  behaviour is retained.
>
>  http://oss.sgi.com/archives/netdev/2003-01/msg00114.html


-- 
Lachlan Andrew  Dept of Computer Science, Caltech
1200 E California Blvd, Mail Code 256-80, Pasadena CA 91125, USA
Ph: +1 (626) 395-8820    Fax: +1 (626) 568-3603
http://netlab.caltech.edu/lachlan

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: min_cwnd.patch --]
[-- Type: text/x-patch; name=min_cwnd.patch, Size: 2252 bytes --]

diff -ruNp linux-2.6.25-rc7/include/net/tcp.h linux-2.6.25-rc7-comments/include/net/tcp.h
--- linux-2.6.25-rc7/include/net/tcp.h	2008-03-27 18:25:07.000000000 -0800
+++ linux-2.6.25-rc7-comments/include/net/tcp.h	2008-04-04 11:05:39.000000000 -0800
@@ -645,7 +645,7 @@ struct tcp_congestion_ops {
 
 	/* return slow start threshold (required) */
 	u32 (*ssthresh)(struct sock *sk);
-	/* lower bound for congestion window (optional) */
+	/* lower bound for congestion window during rate halving (optional) */
 	u32 (*min_cwnd)(const struct sock *sk);
 	/* do new cwnd calculation (required) */
 	void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight);
diff -ruNp linux-2.6.25-rc7/net/ipv4/tcp_cong.c linux-2.6.25-rc7-comments/net/ipv4/tcp_cong.c
--- linux-2.6.25-rc7/net/ipv4/tcp_cong.c	2008-03-27 18:25:07.000000000 -0800
+++ linux-2.6.25-rc7-comments/net/ipv4/tcp_cong.c	2008-04-04 11:05:00.000000000 -0800
@@ -387,6 +387,8 @@ u32 tcp_reno_ssthresh(struct sock *sk)
 EXPORT_SYMBOL_GPL(tcp_reno_ssthresh);
 
 /* Lower bound on congestion window with halving. */
+/* Allows snd_cwnd to reduce to prev_cwnd/4  */
+/*   -- see http://oss.sgi.com/archives/netdev/2003-01/msg00114.html */
 u32 tcp_reno_min_cwnd(const struct sock *sk)
 {
 	const struct tcp_sock *tp = tcp_sk(sk);
diff -ruNp linux-2.6.25-rc7/net/ipv4/tcp_input.c linux-2.6.25-rc7-comments/net/ipv4/tcp_input.c
--- linux-2.6.25-rc7/net/ipv4/tcp_input.c	2008-03-27 18:25:07.000000000 -0800
+++ linux-2.6.25-rc7-comments/net/ipv4/tcp_input.c	2008-04-04 11:07:43.000000000 -0800
@@ -2233,14 +2233,15 @@ static inline void tcp_moderate_cwnd(str
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-/* Lower bound on congestion window is slow start threshold
+/* Lower bound on congestion window during rate halving is *half* of
+ * slow start threshold (see net/ipv4/tcp_cong.c:tcp_reno_min_cwnd() )
  * unless congestion avoidance choice decides to overide it.
  */
 static inline u32 tcp_cwnd_min(const struct sock *sk)
 {
 	const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;
 
-	return ca_ops->min_cwnd ? ca_ops->min_cwnd(sk) : tcp_sk(sk)->snd_ssthresh;
+	return ca_ops->min_cwnd ? ca_ops->min_cwnd(sk) : tcp_sk(sk)->snd_ssthresh / 2;
 }
 
 /* Decrease cwnd each second ack. */

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-04-04 19:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-04  1:00 Why is tcp_reno_min_cwnd() ssthresh/2? Lachlan Andrew
2008-04-04  2:35 ` Xiaoliang "David" Wei
2008-04-04 16:24   ` John Heffner
2008-04-04 18:31     ` Stephen Hemminger
2008-04-04 19:27       ` Lachlan Andrew

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).