netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [TCP 0/4] H-TCP patches on top of Stephens cc framework
@ 2005-05-06 17:37 Baruch Even
  2005-05-06 17:38 ` [PATCH TCP 1/4] Add undo callback to " Baruch Even
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Baruch Even @ 2005-05-06 17:37 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Baruch Even, Douglas Leith, David S.Miller

This is a first post of the H-TCP framework on top of Stephens congestion
control framework. Hopefully the use of the framework will make it easier to
understand the logic of the H-TCP algorithm. It definitely helped me :-)

The code is licensed under the GNU GPL v2, and according to that we know this
gives an implicit patent license to users of this code. An explicit licensing
to OSDL for the purpose of sub-licensing is in the works to alleviate any fear.

Baruch

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

* [PATCH TCP 1/4] Add undo callback to Stephens cc framework
  2005-05-06 17:37 [TCP 0/4] H-TCP patches on top of Stephens cc framework Baruch Even
@ 2005-05-06 17:38 ` Baruch Even
  2005-05-06 17:39 ` [PATCH TCP 2/4] Implement H-TCP congestion control algorithm Baruch Even
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Baruch Even @ 2005-05-06 17:38 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Baruch Even, Douglas Leith, David S.Miller

When undoing a congestion event due to reordering detection, the ssthresh is
multiplied by two. This is incorrect for anything other than (New)Reno, for
example BIC and H-TCP.

This patch adds a callback that these CC algorithms can attach to, the actual
callback is not realized yet for BIC. The callback is already in use in the
H-TCP patches.

Signed-Off-By: Baruch Even <baruch@ev-en.org>

---
 include/net/tcp.h    |    1 +
 net/ipv4/tcp_input.c |    5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)

Index: 2.6.11-stephen-htcp/include/net/tcp.h
===================================================================
--- 2.6.11-stephen-htcp.orig/include/net/tcp.h
+++ 2.6.11-stephen-htcp/include/net/tcp.h
@@ -1196,6 +1196,7 @@ struct tcp_ca_type {
 	void (*set_state)(struct tcp_sock *tp, u8 new_state);
 
 	void (*cwnd_event)(struct tcp_sock *tp, enum tcp_ca_event ev);
+	u32 (*undo_cwnd)(struct tcp_sock *tp);
 
 	struct list_head	list;
 	struct module 		*owner;
Index: 2.6.11-stephen-htcp/net/ipv4/tcp_input.c
===================================================================
--- 2.6.11-stephen-htcp.orig/net/ipv4/tcp_input.c
+++ 2.6.11-stephen-htcp/net/ipv4/tcp_input.c
@@ -1573,7 +1573,10 @@ static void DBGUNDO(struct sock *sk, str
 static void tcp_undo_cwr(struct tcp_sock *tp, int undo)
 {
 	if (tp->prior_ssthresh) {
-		tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1);
+		if (tp->ca_proto->undo_cwnd)
+			tp->snd_cwnd = tp->ca_proto->undo_cwnd(tp);
+		else
+			tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1);
 
 		if (undo && tp->prior_ssthresh > tp->snd_ssthresh) {
 			tp->snd_ssthresh = tp->prior_ssthresh;

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

* [PATCH TCP 2/4] Implement H-TCP congestion control algorithm
  2005-05-06 17:37 [TCP 0/4] H-TCP patches on top of Stephens cc framework Baruch Even
  2005-05-06 17:38 ` [PATCH TCP 1/4] Add undo callback to " Baruch Even
@ 2005-05-06 17:39 ` Baruch Even
  2005-05-06 17:40 ` [PATCH TCP 3/4] Adjust alpha according to RTT timing Baruch Even
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Baruch Even @ 2005-05-06 17:39 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Baruch Even, Douglas Leith, David S.Miller

H-TCP is a congestion control algorithm developed at the Hamilton Institute, by
Douglas Leith and Robert Shorten. It is extending the standard Reno algorithm
with mode switching is thus a relatively simple modification.

H-TCP is defined in a layered manner as it is still a research platform. The
basic form includes the modification of beta according to the ratio of maxRTT
to min RTT and the alpha=2*factor*(1-beta) relation, where factor is dependant
on the time since last congestion.

The other layers improve convergence by adding appropriate factors to alpha.

The following patch implements the H-TCP algorithm in it's basic form.

Signed-Off-By: Baruch Even <baruch@ev-en.org>

---
 net/ipv4/Kconfig    |   10 ++
 net/ipv4/Makefile   |    1 
 net/ipv4/tcp_htcp.c |  198 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 209 insertions(+)

Index: 2.6.11-stephen-htcp/net/ipv4/tcp_htcp.c
===================================================================
--- /dev/null
+++ 2.6.11-stephen-htcp/net/ipv4/tcp_htcp.c
@@ -0,0 +1,198 @@
+/*
+ * H-TCP congestion control. The algorithm is detailed in:
+ * R.N.Shorten, D.J.Leith:
+ *   "H-TCP: TCP for high-speed and long-distance networks"
+ *   Proc. PFLDnet, Argonne, 2004.
+ * http://www.hamilton.ie/net/htcp3.pdf
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+
+#define BETA_MIN	(1<<6)  /* 0.5 with shift << 7 */
+#define BETA_MAX	102	/* 0.8 with shift << 7 */
+
+struct htcp_ca {
+	u32	alpha;		/* Fixed point arith, << 7 */
+	u32	beta;           /* Fixed point arith, << 7 */
+	u32	modeswitch;     /* Delay modeswitch until we had at least one congestion event */
+	u32	ccount;		/* Number of RTTs since last congestion event */
+	u32	minRTT;
+	u32	maxRTT;
+
+	u32	undo_ccount;
+	u32	undo_maxRTT;
+};
+
+static inline void htcp_reset(struct htcp_ca *ca)
+{
+	ca->undo_ccount = ca->ccount;
+	ca->undo_maxRTT = ca->maxRTT;
+
+	ca->ccount = 0;
+}
+
+static u32 htcp_cwnd_undo(struct tcp_sock *tp)
+{
+	struct htcp_ca *ca = tcp_ca(tp);
+	ca->ccount = ca->undo_ccount;
+	ca->maxRTT = ca->undo_maxRTT;
+	return max(tp->snd_cwnd, (tp->snd_ssthresh<<7)/ca->beta);
+}
+
+static inline void measure_rtt(struct tcp_sock *tp)
+{
+	struct htcp_ca *ca = tcp_ca(tp);
+	u32 srtt = tp->srtt>>3;
+
+	/* keep track of minimum RTT seen so far, minRTT is zero at first */
+	if (ca->minRTT > srtt || !ca->minRTT)
+		ca->minRTT = srtt;
+
+	/* max RTT */
+	if (tp->ca_state == TCP_CA_Open && tp->snd_ssthresh < 0xFFFF && ca->ccount > 3) {
+		if (ca->maxRTT < ca->minRTT)
+			ca->maxRTT = ca->minRTT;
+		if (ca->maxRTT < srtt && srtt <= ca->maxRTT+HZ/50)
+			ca->maxRTT = srtt;
+	}
+}
+
+static inline void htcp_beta_update(struct htcp_ca *ca, u32 minRTT, u32 maxRTT)
+{
+	if (ca->modeswitch && minRTT > max(HZ/100, 1) && maxRTT) {
+		ca->beta = (minRTT<<7)/maxRTT;
+		if (ca->beta < BETA_MIN)
+			ca->beta = BETA_MIN;
+		else if (ca->beta > BETA_MAX)
+			ca->beta = BETA_MAX;
+	} else {
+		ca->beta = BETA_MIN;
+		ca->modeswitch = 1;
+	}
+}
+
+static inline void htcp_alpha_update(struct htcp_ca *ca, u32 minRTT)
+{
+	u32 factor = 1;
+	u32 diff = ca->ccount * minRTT; /* time since last backoff */
+
+	if (diff > HZ) {
+		diff -= HZ;
+		factor = 1+ ( 10*diff + ((diff/2)*(diff/2)/HZ) )/HZ;
+	}
+
+	ca->alpha = 2*factor*((1<<7)-ca->beta);
+	if (!ca->alpha)
+		ca->alpha = 1<<7;
+}
+
+/* After we have the rtt data to calculate beta, we'd still prefer to wait one
+ * rtt before we adjust our beta to ensure we are working from a consistent
+ * data.
+ *
+ * This function should be called when we hit a congestion event since only at
+ * that point do we really have a real sense of maxRTT (the queues en route
+ * were getting just too full now).
+ */
+static void htcp_param_update(struct tcp_sock *tp)
+{
+	struct htcp_ca *ca = tcp_ca(tp);
+	u32 minRTT = ca->minRTT;
+	u32 maxRTT = ca->maxRTT;
+
+	htcp_beta_update(ca, minRTT, maxRTT);
+	htcp_alpha_update(ca, minRTT);
+
+	/* add slowly fading memory for maxRTT to accommodate routing changes etc */
+	if (minRTT > 0 && maxRTT > minRTT)
+		ca->maxRTT = minRTT + ((maxRTT-minRTT)*95)/100;
+}
+
+static u32 htcp_recalc_ssthresh(struct tcp_sock *tp)
+{
+	struct htcp_ca *ca = tcp_ca(tp);
+	return max((tp->snd_cwnd * ca->beta) >> 7, 2U);
+}
+
+static void htcp_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt, u32 in_flight)
+{
+	struct htcp_ca *ca = tcp_ca(tp);
+
+	if (in_flight < tp->snd_cwnd)
+		return;
+
+        if (tp->snd_cwnd <= tp->snd_ssthresh) {
+                /* In "safe" area, increase. */
+		if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+			tp->snd_cwnd++;
+	} else {
+		measure_rtt(tp);
+
+                /* In dangerous area, increase slowly.
+		 * In theory this is tp->snd_cwnd += alpha / tp->snd_cwnd
+		 */
+		if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+				tp->snd_cwnd += ca->alpha;
+			tp->snd_cwnd_cnt = 0;
+			ca->ccount++;
+		} else
+			tp->snd_cwnd_cnt++;
+	}
+}
+
+static void htcp_start(struct tcp_sock *tp)
+{
+	struct htcp_ca *ca = tcp_ca(tp);
+	ca->alpha = 1<<7;
+	ca->beta = BETA_MIN;
+	ca->modeswitch = 0;
+	ca->ccount = 0;
+	ca->minRTT = 0;
+	ca->maxRTT = 0;
+}
+
+static void htcp_ca_state(struct tcp_sock *tp, u8 new_state)
+{
+	if (new_state == TCP_CA_CWR || new_state == TCP_CA_Recovery) {
+		htcp_param_update(tp);
+		htcp_reset(tcp_ca(tp));
+	} else if (new_state == TCP_CA_Loss) {
+		htcp_reset(tcp_ca(tp));
+	}
+}
+
+static struct tcp_ca_type htcp = {
+	.start		= htcp_start,
+	.ssthresh	= htcp_recalc_ssthresh,
+	.min_cwnd	= tcp_reno_cwnd_min,
+	.cong_avoid	= htcp_cong_avoid,
+	.set_state	= htcp_ca_state,
+	.undo_cwnd	= htcp_cwnd_undo,
+
+	.owner		= THIS_MODULE,
+	.name		= "htcp",
+};
+
+static int __init htcp_init(void)
+{
+	BUILD_BUG_ON(sizeof(struct htcp_ca) > TCP_CA_PRIV_SIZE);
+	BUILD_BUG_ON(BETA_MIN >= BETA_MAX);
+	tcp_ca_register(&htcp);
+	return 0;
+}
+
+static void __exit htcp_exit(void)
+{
+	tcp_ca_unregister(&htcp);
+}
+
+module_init(htcp_init);
+module_exit(htcp_exit);
+
+MODULE_AUTHOR("Baruch Even");
+MODULE_LICENSE("Unknown for now");
+MODULE_DESCRIPTION("H-TCP");
Index: 2.6.11-stephen-htcp/net/ipv4/Kconfig
===================================================================
--- 2.6.11-stephen-htcp.orig/net/ipv4/Kconfig
+++ 2.6.11-stephen-htcp/net/ipv4/Kconfig
@@ -405,6 +405,16 @@ config TCP_CONG_WESTWOOD
 	TCP Westwood+ significantly increases fairness wrt TCP Reno in 
 	wired networks and throughput over wireless links.   
 
+config TCP_CONG_HTCP
+	tristate "H-TCP"
+	default y
+	---help---
+	H-TCP is a send-side only modifications of the TCP Reno protocol stack
+	that optimizes the performance of TCP congestion control for high speed
+	network links. It uses a modeswitch to change the alpha and beta
+	parameters of TCP Reno based on network conditions and in a way so as
+	to be fair with other Reno and H-TCP flows.
+
 endmenu
 
 
Index: 2.6.11-stephen-htcp/net/ipv4/Makefile
===================================================================
--- 2.6.11-stephen-htcp.orig/net/ipv4/Makefile
+++ 2.6.11-stephen-htcp/net/ipv4/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_IP_PNP) += ipconfig.o
 obj-$(CONFIG_NETFILTER)	+= netfilter/
 obj-$(CONFIG_IP_VS) += ipvs/
 obj-$(CONFIG_IP_TCPDIAG) += tcp_diag.o 
+obj-$(CONFIG_TCP_CONG_HTCP) += tcp_htcp.o
 obj-$(CONFIG_TCP_CONG_VEGAS) += tcp_vegas.o
 obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
 obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o

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

* [PATCH TCP 3/4] Adjust alpha according to RTT timing
  2005-05-06 17:37 [TCP 0/4] H-TCP patches on top of Stephens cc framework Baruch Even
  2005-05-06 17:38 ` [PATCH TCP 1/4] Add undo callback to " Baruch Even
  2005-05-06 17:39 ` [PATCH TCP 2/4] Implement H-TCP congestion control algorithm Baruch Even
@ 2005-05-06 17:40 ` Baruch Even
  2005-05-06 17:41 ` [PATCH TCP 4/4] Switch out when bandwidth changes abruptly Baruch Even
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Baruch Even @ 2005-05-06 17:40 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Baruch Even, Douglas Leith, David S.Miller

This is another H-TCP layer patch. This patch adds an rtt scaling to the alpha
parameter. This increases alpha for large distance networks.

Signed-Off-By: Baruch Even <baruch@ev-en.org>

---
 net/ipv4/tcp_htcp.c |   13 +++++++++++++
 1 files changed, 13 insertions(+)

Index: 2.6.11-stephen-htcp/net/ipv4/tcp_htcp.c
===================================================================
--- 2.6.11-stephen-htcp.orig/net/ipv4/tcp_htcp.c
+++ 2.6.11-stephen-htcp/net/ipv4/tcp_htcp.c
@@ -12,6 +12,10 @@
 #define BETA_MIN	(1<<6)  /* 0.5 with shift << 7 */
 #define BETA_MAX	102	/* 0.8 with shift << 7 */
 
+static int use_rtt_scaling = 1;
+module_param(use_rtt_scaling, int, 0644);
+MODULE_PARM_DESC(use_rtt_scaling, "turn on/off RTT scaling");
+
 struct htcp_ca {
 	u32	alpha;		/* Fixed point arith, << 7 */
 	u32	beta;           /* Fixed point arith, << 7 */
@@ -85,6 +89,15 @@ static inline void htcp_alpha_update(str
 	ca->alpha = 2*factor*((1<<7)-ca->beta);
 	if (!ca->alpha)
 		ca->alpha = 1<<7;
+
+	if (use_rtt_scaling && minRTT) {
+		u32 scale;
+		scale = (HZ<<3)/(10*minRTT);
+		scale = min(max(scale, 1U<<2), 10U<<3); /* clamping ratio to interval [0.5,10]<<3 */
+		ca->alpha = (ca->alpha<<3)/scale;
+		if (!ca->alpha)
+			ca->alpha = 1<<7;
+	}
 }
 
 /* After we have the rtt data to calculate beta, we'd still prefer to wait one

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

* [PATCH TCP 4/4] Switch out when bandwidth changes abruptly
  2005-05-06 17:37 [TCP 0/4] H-TCP patches on top of Stephens cc framework Baruch Even
                   ` (2 preceding siblings ...)
  2005-05-06 17:40 ` [PATCH TCP 3/4] Adjust alpha according to RTT timing Baruch Even
@ 2005-05-06 17:41 ` Baruch Even
  2005-05-06 18:09 ` [TCP 0/4] H-TCP patches on top of Stephens cc framework Greg KH
  2005-05-09 23:22 ` [RFC] TCP congestion infrastructure Stephen Hemminger
  5 siblings, 0 replies; 12+ messages in thread
From: Baruch Even @ 2005-05-06 17:41 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Baruch Even, Douglas Leith, David S.Miller

This is another H-TCP layer patch. This patch adds a bandwidth switcher so that
when a new stream joins we quickly yield bandwidth to it by going back to a
backoff factor of one-half.

For this to work we have a bandwidth estimator and need a new hook for
congestion control algorithms, this is in effect something that can be used
generally and is not necessarily specific to H-TCP. But H-TCP is the only user
for it at this time. A simple use for it is to export it to user-space for a
more accurate bandwidth estimation on the sender side.

Signed-Off-By: Baruch Even <baruch@ev-en.org>

---
 include/net/tcp.h    |    1 
 net/ipv4/tcp_htcp.c  |  138 +++++++++++++++++++++++++++++++++++++++------------
 net/ipv4/tcp_input.c |   10 +++
 3 files changed, 117 insertions(+), 32 deletions(-)

Index: 2.6.11-stephen-htcp/net/ipv4/tcp_htcp.c
===================================================================
--- 2.6.11-stephen-htcp.orig/net/ipv4/tcp_htcp.c
+++ 2.6.11-stephen-htcp/net/ipv4/tcp_htcp.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <net/tcp.h>
 
+#define ALPHA_BASE	(1<<7)  /* 1.0 with shift << 7 */
 #define BETA_MIN	(1<<6)  /* 0.5 with shift << 7 */
 #define BETA_MAX	102	/* 0.8 with shift << 7 */
 
@@ -16,24 +17,40 @@ static int use_rtt_scaling = 1;
 module_param(use_rtt_scaling, int, 0644);
 MODULE_PARM_DESC(use_rtt_scaling, "turn on/off RTT scaling");
 
+static int use_bandwidth_switch = 1;
+module_param(use_bandwidth_switch, int, 0644);
+MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher");
+
 struct htcp_ca {
-	u32	alpha;		/* Fixed point arith, << 7 */
-	u32	beta;           /* Fixed point arith, << 7 */
-	u32	modeswitch;     /* Delay modeswitch until we had at least one congestion event */
-	u32	ccount;		/* Number of RTTs since last congestion event */
+	u16	alpha;		/* Fixed point arith, << 7 */
+	u8	beta;           /* Fixed point arith, << 7 */
+	u8	modeswitch;     /* Delay modeswitch until we had at least one congestion event */
+	u8	ccount;		/* Number of RTTs since last congestion event */
+	u8	undo_ccount;
+	u16	packetcount;
 	u32	minRTT;
 	u32	maxRTT;
+	u32	snd_cwnd_cnt2;
 
-	u32	undo_ccount;
 	u32	undo_maxRTT;
+	u32	undo_old_maxB;
+
+	/* Bandwidth estimation */
+	u32	minB;
+	u32	maxB;
+	u32	old_maxB;
+	u32	Bi;
+	u32	lasttime;
 };
 
 static inline void htcp_reset(struct htcp_ca *ca)
 {
 	ca->undo_ccount = ca->ccount;
 	ca->undo_maxRTT = ca->maxRTT;
+	ca->undo_old_maxB = ca->old_maxB;
 
 	ca->ccount = 0;
+	ca->snd_cwnd_cnt2 = 0;
 }
 
 static u32 htcp_cwnd_undo(struct tcp_sock *tp)
@@ -41,6 +58,7 @@ static u32 htcp_cwnd_undo(struct tcp_soc
 	struct htcp_ca *ca = tcp_ca(tp);
 	ca->ccount = ca->undo_ccount;
 	ca->maxRTT = ca->undo_maxRTT;
+	ca->old_maxB = ca->undo_old_maxB;
 	return max(tp->snd_cwnd, (tp->snd_ssthresh<<7)/ca->beta);
 }
 
@@ -62,8 +80,53 @@ static inline void measure_rtt(struct tc
 	}
 }
 
+static void measure_achieved_throughput(struct tcp_sock *tp, u32 pkts_acked)
+{
+	struct htcp_ca *ca = tcp_ca(tp);
+	u32 now = tcp_time_stamp;
+
+	/* achieved throughput calculations */
+	if (tp->ca_state != TCP_CA_Open && tp->ca_state != TCP_CA_Disorder) {
+		ca->packetcount = 0;
+		ca->lasttime = now;
+		return;
+	}
+
+	ca->packetcount += pkts_acked;
+
+	if (ca->packetcount >= tp->snd_cwnd - (ca->alpha>>7? : 1)
+			&& now - ca->lasttime >= ca->minRTT
+			&& ca->minRTT > 0) {
+		__u32 cur_Bi = ca->packetcount*HZ/(now - ca->lasttime);
+		if (ca->ccount <= 3) {
+			/* just after backoff */
+			ca->minB = ca->maxB = ca->Bi = cur_Bi;
+		} else {
+			ca->Bi = (3*ca->Bi + cur_Bi)/4;
+			if (ca->Bi > ca->maxB)
+				ca->maxB = ca->Bi;
+			if (ca->minB > ca->maxB)
+				ca->minB = ca->maxB;
+		}
+		ca->packetcount = 0;
+		ca->lasttime = now;
+	}
+}
+
 static inline void htcp_beta_update(struct htcp_ca *ca, u32 minRTT, u32 maxRTT)
 {
+	if (use_bandwidth_switch) {
+		u32 maxB = ca->maxB;
+		u32 old_maxB = ca->old_maxB;
+		ca->old_maxB = ca->maxB;
+
+		if (!between(5*maxB, 4*old_maxB, 6*old_maxB)) {
+			ca->beta = BETA_MIN;
+			ca->modeswitch = 0;
+			return;
+		}
+	}
+
 	if (ca->modeswitch && minRTT > max(HZ/100, 1) && maxRTT) {
 		ca->beta = (minRTT<<7)/maxRTT;
 		if (ca->beta < BETA_MIN)
@@ -76,8 +139,9 @@ static inline void htcp_beta_update(stru
 	}
 }
 
-static inline void htcp_alpha_update(struct htcp_ca *ca, u32 minRTT)
+static inline void htcp_alpha_update(struct htcp_ca *ca)
 {
+	u32 minRTT = ca->minRTT;
 	u32 factor = 1;
 	u32 diff = ca->ccount * minRTT; /* time since last backoff */
 
@@ -86,18 +150,17 @@ static inline void htcp_alpha_update(str
 		factor = 1+ ( 10*diff + ((diff/2)*(diff/2)/HZ) )/HZ;
 	}
 
-	ca->alpha = 2*factor*((1<<7)-ca->beta);
-	if (!ca->alpha)
-		ca->alpha = 1<<7;
-
 	if (use_rtt_scaling && minRTT) {
-		u32 scale;
-		scale = (HZ<<3)/(10*minRTT);
+		u32 scale = (HZ<<3)/(10*minRTT);
 		scale = min(max(scale, 1U<<2), 10U<<3); /* clamping ratio to interval [0.5,10]<<3 */
-		ca->alpha = (ca->alpha<<3)/scale;
-		if (!ca->alpha)
-			ca->alpha = 1<<7;
+		factor = (factor<<3)/scale;
+		if (!factor)
+			factor = 1;
 	}
+
+	ca->alpha = 2*factor*((1<<7)-ca->beta);
+	if (!ca->alpha)
+		ca->alpha = ALPHA_BASE;
 }
 
 /* After we have the rtt data to calculate beta, we'd still prefer to wait one
@@ -115,7 +178,7 @@ static void htcp_param_update(struct tcp
 	u32 maxRTT = ca->maxRTT;
 
 	htcp_beta_update(ca, minRTT, maxRTT);
-	htcp_alpha_update(ca, minRTT);
+	htcp_alpha_update(ca);
 
 	/* add slowly fading memory for maxRTT to accommodate routing changes etc */
 	if (minRTT > 0 && maxRTT > minRTT)
@@ -125,6 +188,7 @@ static void htcp_param_update(struct tcp
 static u32 htcp_recalc_ssthresh(struct tcp_sock *tp)
 {
 	struct htcp_ca *ca = tcp_ca(tp);
+	htcp_param_update(tp);
 	return max((tp->snd_cwnd * ca->beta) >> 7, 2U);
 }
 
@@ -142,47 +206,57 @@ static void htcp_cong_avoid(struct tcp_s
 	} else {
 		measure_rtt(tp);
 
+		/* keep track of number of round-trip times since last backoff event */
+		if (ca->snd_cwnd_cnt2++ > tp->snd_cwnd) {
+			ca->ccount++;
+			ca->snd_cwnd_cnt2 = 0;
+			htcp_alpha_update(ca);
+		}
+
                 /* In dangerous area, increase slowly.
 		 * In theory this is tp->snd_cwnd += alpha / tp->snd_cwnd
 		 */
-		if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+		if ((tp->snd_cwnd_cnt++ * ca->alpha)>>7 >= tp->snd_cwnd) {
 			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-				tp->snd_cwnd += ca->alpha;
+				tp->snd_cwnd++;
 			tp->snd_cwnd_cnt = 0;
-			ca->ccount++;
-		} else
-			tp->snd_cwnd_cnt++;
+		}
 	}
 }
 
+static u32 htcp_cwnd_min(struct tcp_sock *tp)
+{
+	return tp->snd_ssthresh;
+}
+
 static void htcp_start(struct tcp_sock *tp)
 {
 	struct htcp_ca *ca = tcp_ca(tp);
-	ca->alpha = 1<<7;
+	memset(ca, 0, sizeof(struct htcp_ca));
+	ca->alpha = ALPHA_BASE;
 	ca->beta = BETA_MIN;
-	ca->modeswitch = 0;
-	ca->ccount = 0;
-	ca->minRTT = 0;
-	ca->maxRTT = 0;
+	printk(KERN_INFO "htcp started for %p/%p\n", tp, ca);
 }
 
 static void htcp_ca_state(struct tcp_sock *tp, u8 new_state)
 {
-	if (new_state == TCP_CA_CWR || new_state == TCP_CA_Recovery) {
-		htcp_param_update(tp);
-		htcp_reset(tcp_ca(tp));
-	} else if (new_state == TCP_CA_Loss) {
+	switch (new_state) {
+	case TCP_CA_CWR:
+	case TCP_CA_Recovery:
+	case TCP_CA_Loss:
 		htcp_reset(tcp_ca(tp));
+		break;
 	}
 }
 
 static struct tcp_ca_type htcp = {
 	.start		= htcp_start,
 	.ssthresh	= htcp_recalc_ssthresh,
-	.min_cwnd	= tcp_reno_cwnd_min,
+	.min_cwnd	= htcp_cwnd_min,
 	.cong_avoid	= htcp_cong_avoid,
 	.set_state	= htcp_ca_state,
 	.undo_cwnd	= htcp_cwnd_undo,
+	.pkts_acked	= measure_achieved_throughput,
 
 	.owner		= THIS_MODULE,
 	.name		= "htcp",
@@ -192,6 +266,8 @@ static int __init htcp_init(void)
 {
 	BUILD_BUG_ON(sizeof(struct htcp_ca) > TCP_CA_PRIV_SIZE);
 	BUILD_BUG_ON(BETA_MIN >= BETA_MAX);
+	if (!use_bandwidth_switch)
+		htcp.pkts_acked = NULL;
 	tcp_ca_register(&htcp);
 	return 0;
 }
Index: 2.6.11-stephen-htcp/include/net/tcp.h
===================================================================
--- 2.6.11-stephen-htcp.orig/include/net/tcp.h
+++ 2.6.11-stephen-htcp/include/net/tcp.h
@@ -1197,6 +1197,7 @@ struct tcp_ca_type {
 
 	void (*cwnd_event)(struct tcp_sock *tp, enum tcp_ca_event ev);
 	u32 (*undo_cwnd)(struct tcp_sock *tp);
+	void (*pkts_acked)(struct tcp_sock *tp, u32 num_acked);
 
 	struct list_head	list;
 	struct module 		*owner;
Index: 2.6.11-stephen-htcp/net/ipv4/tcp_input.c
===================================================================
--- 2.6.11-stephen-htcp.orig/net/ipv4/tcp_input.c
+++ 2.6.11-stephen-htcp/net/ipv4/tcp_input.c
@@ -2030,6 +2030,7 @@ static int tcp_clean_rtx_queue(struct so
 	__u32 now = tcp_time_stamp;
 	int acked = 0;
 	__s32 seq_rtt = -1;
+	u32 pkts_acked = 0;
 
 	while ((skb = skb_peek(&sk->sk_write_queue)) &&
 	       skb != sk->sk_send_head) {
@@ -2041,9 +2042,12 @@ static int tcp_clean_rtx_queue(struct so
 		 * the other end.
 		 */
 		if (after(scb->end_seq, tp->snd_una)) {
-			if (tcp_skb_pcount(skb) > 1)
+			if (tcp_skb_pcount(skb) > 1) {
+				u32 pkts = tcp_skb_pcount(skb);
 				acked |= tcp_tso_acked(sk, skb,
 						       now, &seq_rtt);
+				pkts_acked += pkts - tcp_skb_pcount(skb);
+			}
 			break;
 		}
 
@@ -2056,6 +2060,7 @@ static int tcp_clean_rtx_queue(struct so
 		 */
 		if (!(scb->flags & TCPCB_FLAG_SYN)) {
 			acked |= FLAG_DATA_ACKED;
+			pkts_acked += tcp_skb_pcount(skb);
 		} else {
 			acked |= FLAG_SYN_ACKED;
 			tp->retrans_stamp = 0;
@@ -2091,6 +2096,9 @@ static int tcp_clean_rtx_queue(struct so
 		tcp_ack_packets_out(sk, tp);
 	}
 
+	if (tp->ca_proto->pkts_acked)
+		tp->ca_proto->pkts_acked(tp, pkts_acked);
+
 #if FASTRETRANS_DEBUG > 0
 	BUG_TRAP((int)tp->sacked_out >= 0);
 	BUG_TRAP((int)tp->lost_out >= 0);

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

* Re: [TCP 0/4] H-TCP patches on top of Stephens cc framework
  2005-05-06 17:37 [TCP 0/4] H-TCP patches on top of Stephens cc framework Baruch Even
                   ` (3 preceding siblings ...)
  2005-05-06 17:41 ` [PATCH TCP 4/4] Switch out when bandwidth changes abruptly Baruch Even
@ 2005-05-06 18:09 ` Greg KH
  2005-05-09 23:22 ` [RFC] TCP congestion infrastructure Stephen Hemminger
  5 siblings, 0 replies; 12+ messages in thread
From: Greg KH @ 2005-05-06 18:09 UTC (permalink / raw)
  To: Baruch Even; +Cc: netdev, Douglas Leith, David S.Miller

On Fri, May 06, 2005 at 08:37:29PM +0300, Baruch Even wrote:
> This is a first post of the H-TCP framework on top of Stephens congestion
> control framework. Hopefully the use of the framework will make it easier to
> understand the logic of the H-TCP algorithm. It definitely helped me :-)
> 
> The code is licensed under the GNU GPL v2, and according to that we know this
> gives an implicit patent license to users of this code. An explicit licensing
> to OSDL for the purpose of sub-licensing is in the works to alleviate any fear.

Why would OSDL have anything to do with "sub-licensing" a patent, unless
they want to make money off of it?  Why not do what other companies have
done with GPL granted patents instead?

thanks,

greg k-h

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

* [RFC] TCP congestion infrastructure
  2005-05-06 17:37 [TCP 0/4] H-TCP patches on top of Stephens cc framework Baruch Even
                   ` (4 preceding siblings ...)
  2005-05-06 18:09 ` [TCP 0/4] H-TCP patches on top of Stephens cc framework Greg KH
@ 2005-05-09 23:22 ` Stephen Hemminger
  2005-05-10  0:17   ` David S. Miller
                     ` (2 more replies)
  5 siblings, 3 replies; 12+ messages in thread
From: Stephen Hemminger @ 2005-05-09 23:22 UTC (permalink / raw)
  To: Baruch Even; +Cc: netdev, Baruch Even, Douglas Leith, David S.Miller

I rebased the H-TCP patches on my current work and 2.6.12-rc4 and put them in
	http://developer.osdl.org/shemminger/patches/2.6.12-rc4-tcp/

Includes infrastructure and all the current variants: BIC, Westwood, Vegas
    plus  H-TCP, Hybla

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

* Re: [RFC] TCP congestion infrastructure
  2005-05-09 23:22 ` [RFC] TCP congestion infrastructure Stephen Hemminger
@ 2005-05-10  0:17   ` David S. Miller
  2005-05-10 16:13     ` Stephen Hemminger
  2005-05-10 14:06   ` Baruch Even
  2005-05-10 14:31   ` Baruch Even
  2 siblings, 1 reply; 12+ messages in thread
From: David S. Miller @ 2005-05-10  0:17 UTC (permalink / raw)
  To: shemminger; +Cc: baruch, netdev, doug.leith

From: Stephen Hemminger <shemminger@osdl.org>
Subject: [RFC] TCP congestion infrastructure
Date: Mon, 9 May 2005 16:22:14 -0700

> I rebased the H-TCP patches on my current work and 2.6.12-rc4 and put them in
> 	http://developer.osdl.org/shemminger/patches/2.6.12-rc4-tcp/
> 
> Includes infrastructure and all the current variants: BIC, Westwood, Vegas
>     plus  H-TCP, Hybla

I like it.  Looks fine from here.

This, along with the TSO reworking, will go in at the next
opportunity which is likely 2.6.13 of course.

I'm considering putting the TSO stuff into 2.6.12 because
in many ways it is a bug fix, TSO is fairly broken without
it.  There are some loose ends I need to resolve first though.

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

* Re: [RFC] TCP congestion infrastructure
  2005-05-09 23:22 ` [RFC] TCP congestion infrastructure Stephen Hemminger
  2005-05-10  0:17   ` David S. Miller
@ 2005-05-10 14:06   ` Baruch Even
  2005-05-10 14:31   ` Baruch Even
  2 siblings, 0 replies; 12+ messages in thread
From: Baruch Even @ 2005-05-10 14:06 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Douglas Leith, David S.Miller

Stephen Hemminger wrote:
> I rebased the H-TCP patches on my current work and 2.6.12-rc4 and put them in
> 	http://developer.osdl.org/shemminger/patches/2.6.12-rc4-tcp/
> 
> Includes infrastructure and all the current variants: BIC, Westwood, Vegas
>     plus  H-TCP, Hybla


I compiled westwood and vegas as modules and got:

*** Warning: "tcpdiag_put" [net/ipv4/tcp_westwood.ko] undefined!
*** Warning: "tcpdiag_put" [net/ipv4/tcp_vegas.ko] undefined!

This is due to:

# CONFIG_IP_TCPDIAG is not set

in the .config.

Baruch

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

* Re: [RFC] TCP congestion infrastructure
  2005-05-09 23:22 ` [RFC] TCP congestion infrastructure Stephen Hemminger
  2005-05-10  0:17   ` David S. Miller
  2005-05-10 14:06   ` Baruch Even
@ 2005-05-10 14:31   ` Baruch Even
  2005-05-10 16:11     ` Stephen Hemminger
  2 siblings, 1 reply; 12+ messages in thread
From: Baruch Even @ 2005-05-10 14:31 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Douglas Leith, David S.Miller

Stephen Hemminger wrote:
> I rebased the H-TCP patches on my current work and 2.6.12-rc4 and put them in
> 	http://developer.osdl.org/shemminger/patches/2.6.12-rc4-tcp/
> 
> Includes infrastructure and all the current variants: BIC, Westwood, Vegas
>     plus  H-TCP, Hybla
> 

In the tcpdiag struct you have TCPDIAG_VEGASINFO which is also used by
WestWood. Maybe a change of name is in order?

Baruch

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

* Re: [RFC] TCP congestion infrastructure
  2005-05-10 14:31   ` Baruch Even
@ 2005-05-10 16:11     ` Stephen Hemminger
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2005-05-10 16:11 UTC (permalink / raw)
  To: Baruch Even; +Cc: netdev, Douglas Leith, David S.Miller

On Tue, 10 May 2005 15:31:00 +0100
Baruch Even <baruch@ev-en.org> wrote:

> Stephen Hemminger wrote:
> > I rebased the H-TCP patches on my current work and 2.6.12-rc4 and put them in
> > 	http://developer.osdl.org/shemminger/patches/2.6.12-rc4-tcp/
> > 
> > Includes infrastructure and all the current variants: BIC, Westwood, Vegas
> >     plus  H-TCP, Hybla
> > 
> 
> In the tcpdiag struct you have TCPDIAG_VEGASINFO which is also used by
> WestWood. Maybe a change of name is in order?

I would but, that name is by now committed in the netlink API. Changing it would
break source compatibility.

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

* Re: [RFC] TCP congestion infrastructure
  2005-05-10  0:17   ` David S. Miller
@ 2005-05-10 16:13     ` Stephen Hemminger
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Hemminger @ 2005-05-10 16:13 UTC (permalink / raw)
  To: David S. Miller; +Cc: baruch, netdev, doug.leith

On Mon, 09 May 2005 17:17:11 -0700 (PDT)
"David S. Miller" <davem@davemloft.net> wrote:

> From: Stephen Hemminger <shemminger@osdl.org>
> Subject: [RFC] TCP congestion infrastructure
> Date: Mon, 9 May 2005 16:22:14 -0700
> 
> > I rebased the H-TCP patches on my current work and 2.6.12-rc4 and put them in
> > 	http://developer.osdl.org/shemminger/patches/2.6.12-rc4-tcp/
> > 
> > Includes infrastructure and all the current variants: BIC, Westwood, Vegas
> >     plus  H-TCP, Hybla
> 
> I like it.  Looks fine from here.
> 
> This, along with the TSO reworking, will go in at the next
> opportunity which is likely 2.6.13 of course.
> 
> I'm considering putting the TSO stuff into 2.6.12 because
> in many ways it is a bug fix, TSO is fairly broken without
> it.  There are some loose ends I need to resolve first though.

I'll put tso-reloaded in next set (2.6.12-rc4-tcp2) so if you have a better
version send me it.

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

end of thread, other threads:[~2005-05-10 16:13 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-06 17:37 [TCP 0/4] H-TCP patches on top of Stephens cc framework Baruch Even
2005-05-06 17:38 ` [PATCH TCP 1/4] Add undo callback to " Baruch Even
2005-05-06 17:39 ` [PATCH TCP 2/4] Implement H-TCP congestion control algorithm Baruch Even
2005-05-06 17:40 ` [PATCH TCP 3/4] Adjust alpha according to RTT timing Baruch Even
2005-05-06 17:41 ` [PATCH TCP 4/4] Switch out when bandwidth changes abruptly Baruch Even
2005-05-06 18:09 ` [TCP 0/4] H-TCP patches on top of Stephens cc framework Greg KH
2005-05-09 23:22 ` [RFC] TCP congestion infrastructure Stephen Hemminger
2005-05-10  0:17   ` David S. Miller
2005-05-10 16:13     ` Stephen Hemminger
2005-05-10 14:06   ` Baruch Even
2005-05-10 14:31   ` Baruch Even
2005-05-10 16:11     ` Stephen Hemminger

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