Skip to content

Commit

Permalink
[TCP]: Add High Speed TCP congestion control module.
Browse files Browse the repository at this point in the history
Sally Floyd's high speed TCP congestion control.
This is useful for comparison and research.

Signed-off-by: John Heffner <[email protected]>
Signed-off-by: Stephen Hemminger <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
John Heffner authored and davem330 committed Jun 23, 2005
1 parent 8727076 commit a628d29
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 0 deletions.
11 changes: 11 additions & 0 deletions net/ipv4/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,17 @@ config TCP_CONG_WESTWOOD
TCP Westwood+ significantly increases fairness wrt TCP Reno in
wired networks and throughput over wireless links.

config TCP_CONG_HSTCP
tristate "High Speed TCP"
depends on INET && EXPERIMENTAL
default n
---help---
Sally Floyd's High Speed TCP (RFC 3649) congestion control.
A modification to TCP's congestion control mechanism for use
with large congestion windows. A table indicates how much to
increase the congestion window by when an ACK is received.
For more detail see http://www.icir.org/floyd/hstcp.html

endmenu

source "net/ipv4/ipvs/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions net/ipv4/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ obj-$(CONFIG_IP_TCPDIAG) += tcp_diag.o
obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o
obj-$(CONFIG_TCP_CONG_HSTCP) += tcp_highspeed.o

obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
xfrm4_output.o
181 changes: 181 additions & 0 deletions net/ipv4/tcp_highspeed.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*
* Sally Floyd's High Speed TCP (RFC 3649) congestion control
*
* See http://www.icir.org/floyd/hstcp.html
*
* John Heffner <[email protected]>
*/

#include <linux/config.h>
#include <linux/module.h>
#include <net/tcp.h>


/* From AIMD tables from RFC 3649 appendix B,
* with fixed-point MD scaled <<8.
*/
static const struct hstcp_aimd_val {
unsigned int cwnd;
unsigned int md;
} hstcp_aimd_vals[] = {
{ 38, 128, /* 0.50 */ },
{ 118, 112, /* 0.44 */ },
{ 221, 104, /* 0.41 */ },
{ 347, 98, /* 0.38 */ },
{ 495, 93, /* 0.37 */ },
{ 663, 89, /* 0.35 */ },
{ 851, 86, /* 0.34 */ },
{ 1058, 83, /* 0.33 */ },
{ 1284, 81, /* 0.32 */ },
{ 1529, 78, /* 0.31 */ },
{ 1793, 76, /* 0.30 */ },
{ 2076, 74, /* 0.29 */ },
{ 2378, 72, /* 0.28 */ },
{ 2699, 71, /* 0.28 */ },
{ 3039, 69, /* 0.27 */ },
{ 3399, 68, /* 0.27 */ },
{ 3778, 66, /* 0.26 */ },
{ 4177, 65, /* 0.26 */ },
{ 4596, 64, /* 0.25 */ },
{ 5036, 62, /* 0.25 */ },
{ 5497, 61, /* 0.24 */ },
{ 5979, 60, /* 0.24 */ },
{ 6483, 59, /* 0.23 */ },
{ 7009, 58, /* 0.23 */ },
{ 7558, 57, /* 0.22 */ },
{ 8130, 56, /* 0.22 */ },
{ 8726, 55, /* 0.22 */ },
{ 9346, 54, /* 0.21 */ },
{ 9991, 53, /* 0.21 */ },
{ 10661, 52, /* 0.21 */ },
{ 11358, 52, /* 0.20 */ },
{ 12082, 51, /* 0.20 */ },
{ 12834, 50, /* 0.20 */ },
{ 13614, 49, /* 0.19 */ },
{ 14424, 48, /* 0.19 */ },
{ 15265, 48, /* 0.19 */ },
{ 16137, 47, /* 0.19 */ },
{ 17042, 46, /* 0.18 */ },
{ 17981, 45, /* 0.18 */ },
{ 18955, 45, /* 0.18 */ },
{ 19965, 44, /* 0.17 */ },
{ 21013, 43, /* 0.17 */ },
{ 22101, 43, /* 0.17 */ },
{ 23230, 42, /* 0.17 */ },
{ 24402, 41, /* 0.16 */ },
{ 25618, 41, /* 0.16 */ },
{ 26881, 40, /* 0.16 */ },
{ 28193, 39, /* 0.16 */ },
{ 29557, 39, /* 0.15 */ },
{ 30975, 38, /* 0.15 */ },
{ 32450, 38, /* 0.15 */ },
{ 33986, 37, /* 0.15 */ },
{ 35586, 36, /* 0.14 */ },
{ 37253, 36, /* 0.14 */ },
{ 38992, 35, /* 0.14 */ },
{ 40808, 35, /* 0.14 */ },
{ 42707, 34, /* 0.13 */ },
{ 44694, 33, /* 0.13 */ },
{ 46776, 33, /* 0.13 */ },
{ 48961, 32, /* 0.13 */ },
{ 51258, 32, /* 0.13 */ },
{ 53677, 31, /* 0.12 */ },
{ 56230, 30, /* 0.12 */ },
{ 58932, 30, /* 0.12 */ },
{ 61799, 29, /* 0.12 */ },
{ 64851, 28, /* 0.11 */ },
{ 68113, 28, /* 0.11 */ },
{ 71617, 27, /* 0.11 */ },
{ 75401, 26, /* 0.10 */ },
{ 79517, 26, /* 0.10 */ },
{ 84035, 25, /* 0.10 */ },
{ 89053, 24, /* 0.10 */ },
};

#define HSTCP_AIMD_MAX ARRAY_SIZE(hstcp_aimd_vals)

struct hstcp {
u32 ai;
};

static void hstcp_init(struct tcp_sock *tp)
{
struct hstcp *ca = tcp_ca(tp);

ca->ai = 0;

/* Ensure the MD arithmetic works. This is somewhat pedantic,
* since I don't think we will see a cwnd this large. :) */
tp->snd_cwnd_clamp = min_t(u32, tp->snd_cwnd_clamp, 0xffffffff/128);
}

static void hstcp_cong_avoid(struct tcp_sock *tp, u32 adk, u32 rtt,
u32 in_flight, int good)
{
struct hstcp *ca = tcp_ca(tp);

if (in_flight < tp->snd_cwnd)
return;

if (tp->snd_cwnd <= tp->snd_ssthresh) {
if (tp->snd_cwnd < tp->snd_cwnd_clamp)
tp->snd_cwnd++;
} else {
/* Update AIMD parameters */
if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
ca->ai < HSTCP_AIMD_MAX)
ca->ai++;
} else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) {
while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
ca->ai > 0)
ca->ai--;
}

/* Do additive increase */
if (tp->snd_cwnd < tp->snd_cwnd_clamp) {
tp->snd_cwnd_cnt += ca->ai;
if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
tp->snd_cwnd++;
tp->snd_cwnd_cnt -= tp->snd_cwnd;
}
}
}
}

static u32 hstcp_ssthresh(struct tcp_sock *tp)
{
struct hstcp *ca = tcp_ca(tp);

/* Do multiplicative decrease */
return max(tp->snd_cwnd - ((tp->snd_cwnd * hstcp_aimd_vals[ca->ai].md) >> 8), 2U);
}


static struct tcp_congestion_ops tcp_highspeed = {
.init = hstcp_init,
.ssthresh = hstcp_ssthresh,
.cong_avoid = hstcp_cong_avoid,
.min_cwnd = tcp_reno_min_cwnd,

.owner = THIS_MODULE,
.name = "highspeed"
};

static int __init hstcp_register(void)
{
BUG_ON(sizeof(struct hstcp) > TCP_CA_PRIV_SIZE);
return tcp_register_congestion_control(&tcp_highspeed);
}

static void __exit hstcp_unregister(void)
{
tcp_unregister_congestion_control(&tcp_highspeed);
}

module_init(hstcp_register);
module_exit(hstcp_unregister);

MODULE_AUTHOR("John Heffner");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("High Speed TCP");

0 comments on commit a628d29

Please sign in to comment.