select congestion control with one sysctl
Subsystems (5)
PATCH 1/1 select congestion control with one sysctl
This patch makes selection of congestion control algorithm simpler by using a single sysctl for that purpose, rather than a cascade of sysctls.
The patch also does some minor cleanups to avoid cascade actions between algorithms so that flow control is cleaner.
Possible improvements:
- Use a string when reading/writing from sysctl to make it more friendly to humans.
- And/Or, provide a list of all available congestion control algorithms.
The patch is against 2.6.11-rc4-bk9.
This patch makes selection of congestion control algorithm simpler by using a single sysctl for that purpose, rather than a cascade of sysctls.
The patch also does some minor cleanups to avoid cascade actions between algorithms so that flow control is cleaner.
Possible improvements:
- Use a string when reading/writing from sysctl to make it more friendly to humans
- And/Or, provide a list of all available congestion control algorithms
The patch is against 2.6.11-rc4-bk9.
include/linux/sysctl.h +1 -0
@@ -344,6 +344,7 @@ enumNET_TCP_DEFAULT_WIN_SCALE =105 ,NET_TCP_MODERATE_RCVBUF =106 ,NET_TCP_TSO_WIN_DIVISOR =107 , + NET_TCP_ADV_CONG=108, }; enum {
include/net/tcp.h +10 -14
@@ -597,13 +597,11 @@ extern int sysctl_tcp_adv_win_scale;extern int sysctl_tcp_tw_reuse;extern int sysctl_tcp_frto;extern int sysctl_tcp_low_latency; -extern int sysctl_tcp_westwood; -extern int sysctl_tcp_vegas_cong_avoid;extern int sysctl_tcp_vegas_alpha;extern int sysctl_tcp_vegas_beta;extern int sysctl_tcp_vegas_gamma;extern int sysctl_tcp_nometrics_save; -extern int sysctl_tcp_bic; +extern int sysctl_tcp_adv_cong;extern int sysctl_tcp_bic_fast_convergence;extern int sysctl_tcp_bic_low_window;extern int sysctl_tcp_moderate_rcvbuf;
@@ -1241,7 +1239,8 @@ static __inline__ unsigned int tcp_packe*/ static inline __u32 tcp_recalc_ssthresh (struct tcp_sock *tp) { -if (tcp_is_bic (tp)) { +switch (tp->adv_cong) { +case TCP_BIC :if (sysctl_tcp_bic_fast_convergence && tp->snd_cwnd < tp->bictcp.last_max_cwnd) tp->bictcp.last_max_cwnd
@@ -1253,9 +1252,11 @@ static inline __u32 tcp_recalc_ssthresh(if (tp->snd_cwnd > sysctl_tcp_bic_low_window)return max (tp->snd_cwnd - (tp->snd_cwnd/BICTCP_1_OVER_BETA ),2U ); - } +break ; -return max (tp->snd_cwnd >>1U ,2U ); +default : +return max (tp->snd_cwnd >>1U ,2U ); + } }/* Stop taking Vegas samples for now. */
@@ -1980,24 +1981,19 @@ static inline void tcp_westwood_update_r tp->westwood.rtt = rtt_seq; } -static inline __u32 __tcp_westwood_bw_rttmin (const struct tcp_sock *tp) +static inline __u32 tcp_westwood_bw_rttmin (const struct tcp_sock *tp) {return max ((tp->westwood.bw_est) * (tp->westwood.rtt_min) / (__u32) (tp->mss_cache_std),2U ); } -static inline __u32 tcp_westwood_bw_rttmin (const struct tcp_sock *tp) -{ -return tcp_is_westwood (tp) ?__tcp_westwood_bw_rttmin (tp) :0 ; -} -static inline int tcp_westwood_ssthresh (struct tcp_sock *tp) {__u32 ssthresh =0 ;if (tcp_is_westwood (tp)) { - ssthresh =__tcp_westwood_bw_rttmin (tp); + ssthresh =tcp_westwood_bw_rttmin (tp);if (ssthresh) tp->snd_ssthresh = ssthresh; }
@@ -2010,7 +2006,7 @@ static inline int tcp_westwood_cwnd(stru__u32 cwnd =0 ;if (tcp_is_westwood (tp)) { - cwnd =__tcp_westwood_bw_rttmin (tp); + cwnd =tcp_westwood_bw_rttmin (tp);if (cwnd) tp->snd_cwnd = cwnd; }
net/ipv4/sysctl_net_ipv4.c +8 -24
@@ -602,22 +602,14 @@ ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = &proc_dointvec, }, - { - .ctl_name = NET_TCP_WESTWOOD, - .procname = "tcp_westwood", - .data = &sysctl_tcp_westwood, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .ctl_name = NET_TCP_VEGAS, - .procname = "tcp_vegas_cong_avoid", - .data = &sysctl_tcp_vegas_cong_avoid, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, + { + .ctl_name = NET_TCP_ADV_CONG, + .procname = "tcp_adv_cong", + .data = &sysctl_tcp_adv_cong, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, { .ctl_name = NET_TCP_VEGAS_ALPHA, .procname = "tcp_vegas_alpha",
@@ -643,14 +635,6 @@ ctl_table ipv4_table[] = { .proc_handler = &proc_dointvec, }, { - .ctl_name = NET_TCP_BIC, - .procname = "tcp_bic", - .data = &sysctl_tcp_bic, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { .ctl_name = NET_TCP_BIC_FAST_CONVERGENCE, .procname = "tcp_bic_fast_convergence", .data = &sysctl_tcp_bic_fast_convergence,
net/ipv4/tcp_input.c +74 -46
174 lines not on this page · raw message
David S. Miller
maintainerFor the millionth time, you can't just delete the existing sysctls. That is a user visisble interface.
Instead, you have to make them at least appear to select a single congestion control algorithm as I stated in the following posting:
http://marc.theaimsgroup.com/?l=linux-kernel&m=110909973530321&w=2
Quoted 10 lines · David S. Miller
For the millionth time, you can't just delete the existing sysctls. That is a user visisble interface.
Instead, you have to make them at least appear to select a single congestion control algorithm as I stated in the following posting:
http://marc.theaimsgroup.com/?l=linux-kernel&m=110909973530321&w=2
I am heading in a different direction with making the TCP congestion protocols a real infrastructure. After the initial version gets done, then I will go back and add compatiablity interface hooks as required.
David S. Miller
maintainerQuoted 5 lines · On Wed, 23 Feb 2005 16:23:02 -0800 Stephen Hemminger <[email protected]>…
I am heading in a different direction with making the TCP congestion protocols
a real infrastructure. After the initial version gets done, then I will go back
and add compatiablity interface hooks as required.
Ok, if you want some patch review you know where to send it :-)
Quoted 9 lines · Stephen Hemminger
Quoted 7 lines · David S. Miller
For the millionth time, you can't just delete the existing sysctls. That is a user visisble interface.
Instead, you have to make them at least appear to select a single congestion control algorithm as I stated in the following posting:
Quoted 8 lines
I am heading in a different direction with making the TCP congestion protocols
a real infrastructure. After the initial version gets done, then I will go back
and add compatiablity interface hooks as required.
Wheee! Now I just have to finish this client project and see what you come up with to see if it fits what I need for the selectable DCCP congestion control stuff 8)
Signature · 1 line
- Arnaldo
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
RFC 1/1 TCP congestion schedulers
Since developers want to experiment with different congestion control mechanisms, and the kernel is getting bloated with overlapping data structure and code for multiple algorithms; here is a patch to split out the Reno, Vegas, Westwood, BIC congestion control stuff into an infrastructure similar to the I/O schedulers.
Congestion control protocol is controlled by sysctl net.ipv4.tcp_congestion_control and the boot parameter tcp_congestion_control. The parameter is a lower case string. The congestion control is set when the socket is connected. If you give a bogus value to the parameter, then it warns and falls back to using TCP Reno. TCP Reno is still required, both as a fallback protocol and to allow other code to use it. No attempt was made to do backward compatibility with the old sysctl's (net.ipv4.tcp_bic, ...)
Individual protocols can have parameters but instead of being sysctl's they are done as module parameters. Sysctl hooks are not ref counted so they can't be safely used by modules. Parmeters can be changed via sysfs.
This is not complete and bugs were probably inserted when extracting out the algorithms so more testing is needed.
---
include/linux/sysctl.h +1 -0
@@ -346,6 +346,7 @@ enumNET_TCP_MODERATE_RCVBUF =106 ,NET_TCP_TSO_WIN_DIVISOR =107 ,NET_TCP_BIC_BETA =108 , + NET_TCP_CONG_CONTROL=109, }; enum {
include/linux/tcp.h +10 -39
73 lines not on this page · raw message
include/net/tcp.h +56 -162
253 lines not on this page · raw message
net/ipv4/Kconfig +43 -0
48 lines not on this page · raw message
net/ipv4/Makefile +5 -1
@@ -5,7 +5,8 @@ obj-y := utils.o route.o inetpeer.o protocol.o \ ip_input.o ip_fragment.o ip_forward.o ip_options.o \ ip_output.o ip_sockglue.o \ - tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o tcp_minisocks.o \ + tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ + tcp_minisocks.o tcp_cong.o tcp_reno.o \ datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \ sysctl_net_ipv4.o fib_frontend.o fib_semantics.o fib_hash.o
@@ -23,6 +24,9 @@ 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_VEGAS) += tcp_vegas.o +obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o +obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \ xfrm4_output.o
net/ipv4/sysctl_net_ipv4.c +6 -69
88 lines not on this page · raw message
net/ipv4/tcp_bic.c +194 -0
194 lines not on this page · raw message
net/ipv4/tcp.c +2 -0
@@ -2366,6 +2366,8 @@ void __init tcp_init(void)printk (KERN_INFO "TCP: Hash tables configured " "(established %d bind %d)\n" , tcp_ehash_size <<1 , tcp_bhash_size); + +tcp_ca_register (&tcp_reno); }EXPORT_SYMBOL (tcp_accept);
net/ipv4/tcp_cong.c +112 -0
112 lines not on this page · raw message
net/ipv4/tcp_diag.c +0 -18
@@ -61,7 +61,6 @@ static int tcpdiag_fill(struct sk_buff *struct nlmsghdr *nlh;struct tcp_info *info =NULL ;struct tcpdiag_meminfo *minfo =NULL ; -struct tcpvegas_info *vinfo =NULL ;unsigned char *b = skb->tail; nlh =NLMSG_PUT (skb, pid, seq,TCPDIAG_GETSOCK ,sizeof (*r));
@@ -73,9 +72,6 @@ static int tcpdiag_fill(struct sk_buff *if (ext & (1 <<(TCPDIAG_INFO -1 ))) info =TCPDIAG_PUT (skb,TCPDIAG_INFO ,sizeof (*info)); -if ((tcp_is_westwood (tp) ||tcp_is_vegas (tp)) - && (ext & (1 <<(TCPDIAG_VEGASINFO -1 )))) - vinfo =TCPDIAG_PUT (skb,TCPDIAG_VEGASINFO ,sizeof (*vinfo)); } r->tcpdiag_family = sk->sk_family; r->tcpdiag_state = sk->sk_state;
@@ -166,20 +162,6 @@ static int tcpdiag_fill(struct sk_buff *if (info)tcp_get_info (sk, info); -if (vinfo) { -if (tcp_is_vegas (tp)) { - vinfo->tcpv_enabled = tp->vegas.doing_vegas_now; - vinfo->tcpv_rttcnt = tp->vegas.cntRTT; - vinfo->tcpv_rtt =jiffies_to_usecs (tp->vegas.baseRTT); - vinfo->tcpv_minrtt =jiffies_to_usecs (tp->vegas.minRTT); - }else { - vinfo->tcpv_enabled =0 ; - vinfo->tcpv_rttcnt =0 ; - vinfo->tcpv_rtt =jiffies_to_usecs (tp->westwood.rtt); - vinfo->tcpv_minrtt =jiffies_to_usecs (tp->westwood.rtt_min); - } - } - nlh->nlmsg_len = skb->tail - b;return skb->len;
net/ipv4/tcp_input.c +22 -667
824 lines not on this page · raw message
net/ipv4/tcp_ipv4.c +2 -1
@@ -2058,7 +2058,6 @@ static int tcp_v4_init_sock(struct sock tp->snd_ssthresh =0x7fffffff ;/* Infinity */ tp->snd_cwnd_clamp = ~0 ; tp->mss_cache_std = tp->mss_cache =536 ; - tp->reordering = sysctl_tcp_reordering; sk->sk_state =TCP_CLOSE ;
@@ -2082,6 +2081,8 @@ int tcp_v4_destroy_sock(struct sock *sk)tcp_clear_xmit_timers (sk); +tcp_ca_destroy (tp); +/* Cleanup up the write buffer. */ sk_stream_writequeue_purge (sk);
net/ipv4/tcp_output.c +1 -14
@@ -111,8 +111,7 @@ static void tcp_cwnd_restart(struct tcp_u32 restart_cwnd =tcp_init_cwnd (tp, dst);u32 cwnd = tp->snd_cwnd; -if (tcp_is_vegas (tp)) -tcp_vegas_enable (tp); +tcp_ca_event (tp,CA_EVENT_CWND_RESTART ); tp->snd_ssthresh =tcp_current_ssthresh (tp); restart_cwnd =min (restart_cwnd, cwnd);
@@ -304,18 +303,6 @@ static int tcp_transmit_skb(struct sock (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); } -/* -* If the connection is idle and we are restarting, -* then we don't want to do any Vegas calculations -* until we get fresh RTT samples. So when we -* restart, we reset our Vegas state to a clean -* slate. After we get acks for this flight of -* packets, _then_ we can make Vegas calculations -* again. -*/ -if (tcp_is_vegas (tp) &&tcp_packets_in_flight (tp) ==0 ) -tcp_vegas_enable (tp); - th = (struct tcphdr *)skb_push (skb, tcp_header_size); skb->h.th = th;skb_set_owner_w (skb, sk);
net/ipv4/tcp_reno.c +63 -0
63 lines not on this page · raw message
net/ipv4/tcp_vegas.c +381 -0
381 lines not on this page · raw message
net/ipv4/tcp_westwood.c +326 -0
326 lines not on this page · raw message
Re: [RFC] TCP congestion schedulers
Cool. :) Here's High Speed TCP.
-John
---
/*
* 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 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 ((sizeof (hstcp_aimd_vals) / sizeof (struct hstcp_aimd_val)) - 1)
struct hstcp_ca {
u32 ai;
};static void hstcp_start(struct tcp_sock *tp)
{
struct hstcp_ca *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)
{
struct hstcp_ca *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 *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_ca_type tcp_highspeed = {
.start = hstcp_start,
.ssthresh = hstcp_ssthresh,
.min_cwnd = tcp_reno_cwnd_min,
.cong_avoid = hstcp_cong_avoid,
.owner = THIS_MODULE,
.name = "highspeed"
};static int __init hstcp_init(void)
{
BUILD_BUG_ON(sizeof(struct hstcp_ca) > TCP_CA_PRIV_SIZE);
tcp_ca_register(&tcp_highspeed);
return 0;
}static void __exit hstcp_exit(void)
{
tcp_ca_unregister(&tcp_highspeed);
}module_init(hstcp_init);module_exit(hstcp_exit);
MODULE_AUTHOR("John Heffner");MODULE_LICENSE("GPL");MODULE_DESCRIPTION("High Speed TCP");
Re: [RFC] TCP congestion schedulers
In reply to Stephen HemmingerThis fixes a null pointer dereference when closing listen sockets.
-John
===== include/net/tcp.h 1.107 vs 1.108 =====
include/net/tcp.h +1 -1
@@ -1219,7 +1219,7 @@static inline void tcp_set_ca_state (struct tcp_sock *tp,u8 ca_state) { -if (tp->ca_proto->set_state) +if (tp->ca_proto && tp->ca_proto->set_state) tp->ca_proto->set_state (tp, ca_state); tp->ca_state = ca_state; }
David S. Miller
maintainerRe: [RFC] TCP congestion schedulers
In reply to Stephen Hemmingerinclude/linux/tcp.h struct tcp_sock { · line 405
Quoted 4 lines · On Mon, 14 Mar 2005 15:17:26 -0800 Stephen Hemminger <[email protected]>…
include/linux/tcp.h +4
-0+/* Hook for advanced congestion control */ +struct tcp_ca_type *ca_proto; +#define TCP_CA_PRIV_SIZE 48 +u8 *ca_priv[TCP_CA_PRIV_SIZE ];
An array of 48 pointers to "u8" eh? :-)
It happens to work, but you're using too much space (specifically: 48 * sizeof(u8 *)) as a side effect.
Otherwise, the only comment I have is that we lose the tcp_diag info. Maybe create a "tcpdiag_put" method in there so we can retain that.
I'm also not so religious anymore about retaining the existing sysctl functionality to enable/disable ca algs.
Re: [RFC] TCP congestion schedulers
Quoted 13 lines · David S. Miller
include/linux/tcp.h struct tcp_sock { · line 405
Quoted 4 lines · On Mon, 14 Mar 2005 15:17:26 -0800 Stephen Hemminger <[email protected]>…
include/linux/tcp.h +4
-0+/* Hook for advanced congestion control */ +struct tcp_ca_type *ca_proto; +#define TCP_CA_PRIV_SIZE 48 +u8 *ca_priv[TCP_CA_PRIV_SIZE ];An array of 48 pointers to "u8" eh? :-)
It happens to work, but you're using too much space (specifically: 48 *
sizeof(u8 *)) as a side effect.
Quoted 6 lines
Otherwise, the only comment I have is that we lose the
tcp_diaginfo. Maybe create a "tcpdiag_put" method in there so we can retain that.I'm also not so religious anymore about retaining the existing sysctl functionality to enable/disable ca algs.
I haven't looked over this patch completely, so I may well be saying something stupid, but if possible, please don't use the tcp/TCP prefix where you think this
code can be used by other inet transport protocols, such as DCCP. I'll try to review this patch this weekend to see if this is possible or if I'm on crack now 8)
- Arnaldo
Re: [RFC] TCP congestion schedulers
Quoted 7 lines · Arnaldo Carvalho de Melo
Quoted 2 lines
I'm also not so religious anymore about retaining the existing sysctl functionality to enable/disable ca algs.
I haven't looked over this patch completely, so I may well be saying something stupid, but if possible, please don't use the tcp/TCP prefix where you think this
code can be used by other inet transport protocols, such as DCCP.
Yes, that would be really nice.
Also heres another thought: if we can have multiple sockets, destined to the same receiver, to share the same congestion state. This is motivated from the CM idea the MIT folks were preaching a few years ago - look at RFC 3124 and the MIT website which had some crude linux code back then as well as tons of papers. I think
that scheme may need to hook up to tc to work well.
cheers,
jamal
Re: [RFC] TCP congestion schedulers
Quoted 10 lines · jamal
Quoted 7 lines · Arnaldo Carvalho de Melo
Quoted 2 lines
I'm also not so religious anymore about retaining the existing sysctl functionality to enable/disable ca algs.
I haven't looked over this patch completely, so I may well be saying something stupid, but if possible, please don't use the tcp/TCP prefix where you think this
code can be used by other inet transport protocols, such as DCCP.
Quoted 8 lines
Yes, that would be really nice.
Also heres another thought: if we can have multiple sockets, destined to the same receiver, to share the same congestion state. This is motivated from the CM idea the MIT folks were preaching a few years ago - look at RFC 3124 and the MIT website which had some crude linux code back then as well as tons of papers. I think
that scheme may need to hook up to tc to work well.
The DCCP drafts mention that they choose not to require the CM, but yes, it is something to consider anyway, its interesting stuff.
Again without looking at the patch fully, the tcp_sock passing to this infrastructure
would have to go away and instead chunk out the needed members out of tcp_sock and into a congestion_info struct that would be a member of both tcp_sock and dccp_sock, and this one would be the one passed to this infrastructure.
In the end we may well give Sally et al some new CCIDs for free :-P
Signature · 1 line
- Arnaldo
Re: [RFC] TCP congestion schedulers
Quoted 23 lines · On Fri, 18 Mar 2005 13:13:45 -0300 Arnaldo Carvalho de Melo…
Quoted 10 lines · jamal
Quoted 7 lines · Arnaldo Carvalho de Melo
Quoted 2 lines
I'm also not so religious anymore about retaining the existing sysctl functionality to enable/disable ca algs.
I haven't looked over this patch completely, so I may well be saying something stupid, but if possible, please don't use the tcp/TCP prefix where you think this
code can be used by other inet transport protocols, such as DCCP.Quoted 8 lines
Yes, that would be really nice.
Also heres another thought: if we can have multiple sockets, destined to the same receiver, to share the same congestion state. This is motivated from the CM idea the MIT folks were preaching a few years ago - look at RFC 3124 and the MIT website which had some crude linux code back then as well as tons of papers. I think
that scheme may need to hook up to tc to work well.The DCCP drafts mention that they choose not to require the CM, but yes, it is something to consider anyway, its interesting stuff.
Quoted 7 lines
Again without looking at the patch fully, the
tcp_sockpassing to this infrastructure
would have to go away and instead chunk out the needed members out oftcp_sockand into acongestion_infostruct that would be a member of bothtcp_sockanddccp_sock, and this one would be the one passed to this infrastructure.In the end we may well give Sally et al some new CCIDs for free :-P
Let's abstract it for TCP first, then as a later patch reduce the scope and generalize it.
Re: [RFC] TCP congestion schedulers
Quoted 32 lines · Stephen Hemminger
Quoted 29 lines · On Fri, 18 Mar 2005 13:13:45 -0300 Arnaldo Carvalho de Melo…
Quoted 10 lines · jamal
Quoted 7 lines · Arnaldo Carvalho de Melo
Quoted 2 lines
I'm also not so religious anymore about retaining the existing sysctl functionality to enable/disable ca algs.
I haven't looked over this patch completely, so I may well be saying something stupid, but if possible, please don't use the tcp/TCP prefix where you think this
code can be used by other inet transport protocols, such as DCCP.Quoted 8 lines
Yes, that would be really nice.
Also heres another thought: if we can have multiple sockets, destined to the same receiver, to share the same congestion state. This is motivated from the CM idea the MIT folks were preaching a few years ago - look at RFC 3124 and the MIT website which had some crude linux code back then as well as tons of papers. I think
that scheme may need to hook up to tc to work well.The DCCP drafts mention that they choose not to require the CM, but yes, it is something to consider anyway, its interesting stuff.
Again without looking at the patch fully, the
tcp_sockpassing to this infrastructure
would have to go away and instead chunk out the needed members out oftcp_sockand into acongestion_infostruct that would be a member of bothtcp_sockanddccp_sock, and this one would be the one passed to this infrastructure.
Quoted 4 lines
Quoted 1 line
In the end we may well give Sally et al some new CCIDs for free :-P
Let's abstract it for TCP first, then as a later patch reduce the scope and generalize it.
Fine with me, just wanted to trow these thoughts so that when working on it you think about it :-)
Signature · 1 line
- Arnaldo
Re: [RFC] TCP congestion schedulers
In reply to Stephen HemmingerQuoted 5 lines · Stephen Hemminger
Since developers want to experiment with different congestion control mechanisms, and the kernel is getting bloated with overlapping data structure and code for multiple algorithms; here is a patch to split out the Reno, Vegas, Westwood, BIC congestion control stuff into an infrastructure similar to the I/O schedulers.
[...]
Did you do any benchmarks to check that wont slow it down?
I would recommend to try it on a IA64 machine if possible. In the past we found that adding indirect function calls on IA64 to networking caused measurable slowdowns in macrobenchmarks.
In that case it was LSM callbacks, but your code looks like it will add even more.
One way to avoid this concern would be to set up the "standard" congestion avoidance in a way that it could be inlined.
-Andi
Re: [RFC] TCP congestion schedulers
Quoted 10 lines · Andi Kleen
Quoted 5 lines · Stephen Hemminger
Since developers want to experiment with different congestion control mechanisms, and the kernel is getting bloated with overlapping data structure and code for multiple algorithms; here is a patch to split out the Reno, Vegas, Westwood, BIC congestion control stuff into an infrastructure similar to the I/O schedulers.
[...]
Quoted 7 lines
Did you do any benchmarks to check that wont slow it down?
I would recommend to try it on a IA64 machine if possible. In the past we found that adding indirect function calls on IA64 to networking caused measurable slowdowns in macrobenchmarks.
In that case it was LSM callbacks, but your code looks like it will add even more.
Is there a canonical benchmark?
Would you really expect a single extra indirect call per ack to have a significant performance impact? This is surprising to me. Where does the cost come from? Replacing instruction cache lines?
-John
David S. Miller
maintainerRe: [RFC] TCP congestion schedulers
Quoted 3 lines · On Mon, 21 Mar 2005 16:25:56 -0500 (EST) John Heffner <[email protected]> wrote:
Would you really expect a single extra indirect call per ack to have a significant performance impact? This is surprising to me. Where does the cost come from? Replacing instruction cache lines?
Maybe not for ACK processing (that's very thick already) but perhaps for a lighter fast path definitely so.
Re: [RFC] TCP congestion schedulers
Quoted 10 lines · David S. Miller
Quoted 3 lines · On Mon, 21 Mar 2005 16:25:56 -0500 (EST) John Heffner <[email protected]> wrote:
Would you really expect a single extra indirect call per ack to have a significant performance impact? This is surprising to me. Where does the cost come from? Replacing instruction cache lines?
Maybe not for ACK processing (that's very thick already) but perhaps for a lighter fast path definitely so.
According to my tests (wrapping tcp_ack with rdtsc's) it takes about 3000 clocks to do tcp_ack() even for fast path, slow path is not much slower in most cases and anyway most of the time is spent either handling SACKs or remove packets from the transmit queue (clean_rtx).
I doubt if the extra calls by function are going to be that much of an issue.
Now, if I knew how to improve performance of the clean_rtx case that would give a boost to ack performance.
Baruch
Re: [RFC] TCP congestion schedulers
In reply to John HeffnerQuoted 16 lines · John Heffner
Quoted 13 lines · Andi Kleen
Quoted 5 lines · Stephen Hemminger
Since developers want to experiment with different congestion control mechanisms, and the kernel is getting bloated with overlapping data structure and code for multiple algorithms; here is a patch to split out the Reno, Vegas, Westwood, BIC congestion control stuff into an infrastructure similar to the I/O schedulers.
[...]
Did you do any benchmarks to check that wont slow it down?
Quoted 8 lines
Quoted 5 lines
I would recommend to try it on a IA64 machine if possible. In the past we found that adding indirect function calls on IA64 to networking caused measurable slowdowns in macrobenchmarks.
In that case it was LSM callbacks, but your code looks like it will add even more.Is there a canonical benchmark?
I would put-forth netperf - but then I'm of course biased. It is reasonably straightforward to run, is sophisticated enough to look for interesting things, and not so big as some benchmarketing benchmarks that require other software besides the stack (eg web servers and whatnot).
If using netperf (not to be confused with Linux versions) versions < 2.4.0 then make sure it is compiled with the makefile edited to have -DUSE_PROC_STAT and _NOT_ have -DHISTOGRAM or -DINTERVALS. If using the rc1 of 2.4.0, just typing "configure" after unpacking the tar file should suffice under linux, but before compiling make sure config.h has a "USE_PROC_STAT" in it. If it is missing USE_PROC_STAT then add a --enable-cpuutil=procstat to the configure step.
Be certain to request CPU utilization numbers with the -c/-C options. Probably best to request confidence intervals. I'd suggest a "128x32" TCP_STREAM test and a "1x1" TCP_RR test. So, something along the lines of:
netperf -H <remote> -i 10,3 -I 99,5 -l 60 -t TCP_STREAM -- -s 128K -S 128K -m 32K
to have netperf reqeust 128KB socket buffers, and pass 32KB in each call to send. Each iteration lasting 60 seconds, and running at least three and no more than 10 iterations to get to the point that it is 99% certain ("confident") that the reported mean for throughput and CPU util is within +/- 2.5% of the actual mean. You can make that -I 99,2 to be +/- 1% at the risk of having a harder time hitting the confidence intervals. If at first you do not hit the confidence intervals you can increase the values in -i up to 30 and/or increase the iteration run time with -l.
For the TCP_RR test:
netperf -H <remote> -I 10,3 -I 99,5 -l 60 -t TCP_RR
which will be as above except running a TCP_RR test. The default in a TCP_RR test is to have a single-byte request and a single-byte response.
If you grab 2.4.0rc1 and run on an MP system, it may be good for reproducability to use the -T option to pin netperf and/or netserver to specific CPUs.
-T 0 will attempt to bind both netperf and netserver to CPU 0
-T 1,0 will attempt to bind netperf to CPU 1 and netserver to CPU 0
-T 0, will bind netperf to CPU 0 and leave netserver floating
-T ,1 will bind netserver to CPU 1 and leave netperf floating
I would suggest two sitations - netperf/netserver bound to the same CPU as that taking interrupts from the NIC, and one where it is not. How broad the "where it is not" case needs/wants to be depends on just how many degrees of "not the same CPU" as one hase on the system (thinking NUMA).
netperf bits can be found at:
ftp://ftp.cup.hp.com/dist/networking/benchmarks/netperf/
with the 2.4.0rc1 bits in the experimental/ subdirectory. There is a Debian package floating around somewhere but I cannot recall the revision of netperf on which it is based so probably best to grab source bits and compile them.
Interrupt avoidance/coalescing may have a noticable effect on the single-stream netperf TCP_RR performance, capping it at a lower transaction per second rating no matter the increase in CPU util. So, it is very important to include the CPU util measurements. Similarly, if a system can already max-out a GbE link, just looking at Bits per second does not sufice.
For situations where the CPU utilization measurement mechanism is questionable (I'm still not sure about the -DUSE_PROC_STAT stuff and interrupt time...any comments there most welcome) it may be preferred to run aggregate tests. Netperf2 has no explicit synchronization, but if one is content with "stopwatch" accuracy, aggregate performance along the lines of:
for i in 1 2 ... N
do
netperf -t TCP_RR -H <remote> -i 30 -L 60 -P 0 -v 0 & done
may suffice. The -P 0 stuff disables output of the test headers. The -v 0 will cause just the Single Figure of Merit (SFM) to be displayed - in this case the transaction per second rate. Here the -i 30 is to make each instance of netperf run 30 iterations. The idea being that at least 28 of them will be while the other N-1 netperfs are running. And, hitting the (default -I 99,5) confidence interval gives us some confidence that any skew is reasonably close to epsilon.
The idea is to take N high enough to saturate the CPU(s) in the system and peak the aggregate transaction rate. Single-byte is used to avoid pegging the link on bits per second. Since this is "stopwatch" I tend to watch to make sure that they all start and end "close" to one another. (NB the combination of -i 30 and -l 60 means the test will run for an hour...alter at your discression)
For aggregate tests it is generally best to have three systems - the System Under Test (SUT) and a pair or more of LG's - sometimes just using a pair of systems saturates before driving the SUT with two or more LGs would.
Quoted 3 lines
Would you really expect a single extra indirect call per ack to have a significant performance impact? This is surprising to me. Where does the cost come from? Replacing instruction cache lines?
I don't have specific data on hand, but the way the selinux stuff (used?) to be implemented did indeed not run very well at all even when selinux was disabled (enabled was another story entirely...)
Even if a single extra indirect call is nearly epsilon, the "thousand cuts" principle would apply. Enough of them and the claims about other OSes having faster networking may actually become true - if it isn't true already. But I may be drifting...
rick jones
Re: [RFC] TCP congestion schedulers
Quoted 1 line · Rick Jones
I would put-forth netperf - but then I'm of course biased. It is
I think that was one of the benchmarks where the ia64 slowdown with LSM was diagnosed; netperf suffered some 10-15% degradation. And that was just with the capability module loaded, no fancy stuff going on. After we hacked up LSM to inline the capability checks in the default case, performance was back to normal.
We didn't bother to pin-point where the loss actually occured, but my suspicion is the major offender was the per-skb check.
Olaf
Signature · 2 lines
Olaf Kirch | --- o --- Nous sommes du soleil we love when we play [email protected] | / | \ sol.dhoop.naytheet.ah kin.ir.samse.qurax
Re: [RFC] TCP congestion schedulers
In reply to John HeffnerQuoted 14 lines · John Heffner
Quoted 12 lines · Andi Kleen
Quoted 5 lines · Stephen Hemminger
Since developers want to experiment with different congestion control mechanisms, and the kernel is getting bloated with overlapping data structure and code for multiple algorithms; here is a patch to split out the Reno, Vegas, Westwood, BIC congestion control stuff into an infrastructure similar to the I/O schedulers.
[...]
Did you do any benchmarks to check that wont slow it down?
Quoted 7 lines
Quoted 5 lines
I would recommend to try it on a IA64 machine if possible. In the past we found that adding indirect function calls on IA64 to networking caused measurable slowdowns in macrobenchmarks.
In that case it was LSM callbacks, but your code looks like it will add even more.Is there a canonical benchmark?
For the LSM case we saw the problem with running netperf over loopback. It added one or two hooks per packet, but it already made a noticeable difference on IA64 boxes.
On other systems it is unnoticeable.
Quoted 3 lines
Would you really expect a single extra indirect call per ack to have a significant performance impact? This is surprising to me. Where does the cost come from? Replacing instruction cache lines?
I was never quite clear. Some instruction stalls in the CPUs. One not very good theory was that McKinley really likes to have its jump registers loaded early for indirect calls, and gcc doesn't even attempt this.
-Andi
Re: [RFC] TCP congestion schedulers
Quoted 33 lines · On 22 Mar 2005 08:41:22 +0100 Andi Kleen <[email protected]> wrote:
Quoted 14 lines · John Heffner
Quoted 12 lines · Andi Kleen
Quoted 5 lines · Stephen Hemminger
Since developers want to experiment with different congestion control mechanisms, and the kernel is getting bloated with overlapping data structure and code for multiple algorithms; here is a patch to split out the Reno, Vegas, Westwood, BIC congestion control stuff into an infrastructure similar to the I/O schedulers.
[...]
Did you do any benchmarks to check that wont slow it down?
Quoted 7 lines
Quoted 5 lines
I would recommend to try it on a IA64 machine if possible. In the past we found that adding indirect function calls on IA64 to networking caused measurable slowdowns in macrobenchmarks.
In that case it was LSM callbacks, but your code looks like it will add even more.Is there a canonical benchmark?
For the LSM case we saw the problem with running netperf over loopback. It added one or two hooks per packet, but it already made a noticeable difference on IA64 boxes.
On other systems it is unnoticeable.
Quoted 3 lines
Would you really expect a single extra indirect call per ack to have a significant performance impact? This is surprising to me. Where does the cost come from? Replacing instruction cache lines?
Quoted 6 lines
I was never quite clear. Some instruction stalls in the CPUs. One not very good theory was that McKinley really likes to have its jump registers loaded early for indirect calls, and gcc doesn't even attempt this.
-Andi
Running on 2 Cpu Opteron using netperf loopback mode shows that the change is very small when averaged over 10 runs. Overall there is
a .28% decrease in CPU usage and a .96% loss in throughput. But both those values are less than twice standard deviation which was .4% for the CPU measurements and .8% for the performance measurements. I can't see it as a worth bothering unless there is some big money benchmark on the line, in which case it would make more sense to look at other optimizations of the loopback path.
Re: [RFC] TCP congestion schedulers
Quoted 8 lines
Running on 2 Cpu Opteron using netperf loopback mode shows that the change is very small when averaged over 10 runs. Overall there is
a .28% decrease in CPU usage and a .96% loss in throughput. But both those values are less than twice standard deviation which was .4% for the CPU measurements and .8% for the performance measurements. I can't see it as a worth bothering unless there is some big money benchmark on the line, in which case it would make more sense to look at other optimizations of the loopback path.
Opteron has no problems with indirect calls, IA64 seems to be different though.
But when you see noticeable differences even on a Opteron I find it somewhat worrying.
-Andi
Re: [RFC] TCP congestion schedulers
Quoted 11 lines · On 29 Mar 2005 17:25:38 +0200 Andi Kleen <[email protected]> wrote:
Quoted 8 lines
Running on 2 Cpu Opteron using netperf loopback mode shows that the change is very small when averaged over 10 runs. Overall there is
a .28% decrease in CPU usage and a .96% loss in throughput. But both those values are less than twice standard deviation which was .4% for the CPU measurements and .8% for the performance measurements. I can't see it as a worth bothering unless there is some big money benchmark on the line, in which case it would make more sense to look at other optimizations of the loopback path.Opteron has no problems with indirect calls, IA64 seems to be different though.
Getting IA64 setup today, to check.
Quoted 2 lines
But when you see noticeable differences even on a Opteron I find it somewhat worrying.
The difference was so tiny that it is in the noise of the measurements.
Re: [RFC] TCP congestion schedulers
I took the liberty of asking one of the IA64 guru's about the indirect calls. This is what he had to say (reposted with his permision if not my complete comprehension :)
<excerpt>
McKinley-type cores (includes Madison, etc.)
do not have indirect branch target hardware. Instead, indirect branches are executed as follows:
At the time an indirect branch is fetched, the frontend reads the contents of the branch register that contains the branch target. The contents of that register is then used as the predicted target.
For example, "br.call.sptk.many rp=b6" would read register "b6" at the time the "br.call" is fetched by the frontend and then the contents of "b6" is used as the predicted target.
This has the following implications:
(1) To _guarantee_ correct prediction, the branch register has to be loaded way before the indirect branch direction (at least 6 front-end L1I cache accesses; which is up to 6 bundle-pairs or 36 instructions, I believe).
(2) If (1) isn't possible (it often isn't, in small functions), another possibility is to test whether the branch targets one of a few common targets and, if so, invoke those targets via direct branches. This is generally done automatically by compilers (at least if there is PBO info or a programmer-provided hint available), but sadly GCC doesn't do this at the moment.
The good news is that since McKinley-types cores don't have complicated branch-target predictors, misprediction penalty is _relative_ small (10 cycles). The bad news is that the network path is extremely sensitive to even such relatively small penalities, it does make a significant difference.
As mentioned earlier, we could fix some of the most egregious effects with a "call_likely" macro which hints which target(s) are the most likely ones.
</excerpt>
rick jones
netperf feedback always welcome...
Re: [RFC] TCP congestion schedulers
Quoted 5 lines · Rick Jones
<excerpt>
McKinley-type cores (includes Madison, etc.)
do not have indirect branch target hardware. Instead, indirect branches are executed as follows:
[...]
Quoted 4 lines
(1) To _guarantee_ correct prediction, the branch register has to be loaded way before the indirect branch direction (at least 6 front-end L1I cache accesses; which is up to 6 bundle-pairs or 36 instructions, I believe).
That's horrendous. Indirect calls are a performance win vs conditional branching on more sensible architectures and it's used quite extensively in various parts of the kernel. It really makes one wonder if dealing with this quirk is worth the trouble.
Signature · 1 line
Mathematics is the supreme nostalgia of our time.
Re: [RFC] TCP congestion schedulers
In reply to Andi KleenQuoted 6 lines · Andi Kleen
Quoted 1 line · John Heffner
Is there a canonical benchmark?
For the LSM case we saw the problem with running netperf over loopback. It added one or two hooks per packet, but it already made a noticeable difference on IA64 boxes.
The motivation for my question is that I get very unpredictable performance over loopback with UP for all architectures, often varying by more than a factor of two. I haven't really tried to track down the cause, but an important characteristic seems to be that the greater the differential between the CPU utilization of the sender and the receiver, the slower the throughput. (But I'm not sure if there's a causal relation here.) Maybe this is simply scheduler strangeness, since it doesn't seem to be an issue that I've noticed on SMP. Has anyone seen this or know offhand what's going on?
The only ia64 I have on which I can boot kernels is a UP box.
-John
David S. Miller
maintainerRe: [RFC] TCP congestion schedulers
Quoted 9 lines · On Tue, 29 Mar 2005 14:32:33 -0500 (EST) John Heffner <[email protected]> wrote:
The motivation for my question is that I get very unpredictable performance over loopback with UP for all architectures, often varying by more than a factor of two. I haven't really tried to track down the cause, but an important characteristic seems to be that the greater the differential between the CPU utilization of the sender and the receiver, the slower the throughput. (But I'm not sure if there's a causal relation here.) Maybe this is simply scheduler strangeness, since it doesn't seem to be an issue that I've noticed on SMP. Has anyone seen this or know offhand what's going on?
It could be L2 cache-coloring effects as well. Try to keep the working set size smaller than the L2 cache size of the cpu you are on.
Re: [RFC] TCP congestion schedulers
Quoted 2 lines
It could be L2 cache-coloring effects as well. Try to keep the working set size smaller than the L2 cache size of the cpu you are on.
When/if using netperf, it will send from and recv to a "ring" of buffers one larger than the reported (as opposed to requested) socket buffer size divided by the send/recv buffer size. Controlled via the -W global command-line option.
rick jones
Re: [RFC] TCP congestion schedulers
In reply to Andi KleenQuoted 10 lines · Andi Kleen
Quoted 5 lines · Stephen Hemminger
Since developers want to experiment with different congestion control mechanisms, and the kernel is getting bloated with overlapping data structure and code for multiple algorithms; here is a patch to split out the Reno, Vegas, Westwood, BIC congestion control stuff into an infrastructure similar to the I/O schedulers.
[...]
Quoted 7 lines
Did you do any benchmarks to check that wont slow it down?
I would recommend to try it on a IA64 machine if possible. In the past we found that adding indirect function calls on IA64 to networking caused measurable slowdowns in macrobenchmarks.
In that case it was LSM callbacks, but your code looks like it will add even more.
For the record, here are some benchmarks from an ia64 over GigE. I set the MTU to 564 so it actually stressed the CPU. Numbers are throughput (10^6 bits/sec).
Command line used: netperf -H 192.168.1.3 -l -1000000000 -c -C -v 2.
The sender was a 1-CPU 900 MHz Itanium2. The receiver was a 1-CPU 2.4 GHz Pentium 4. The sender reported over 99% utilization; the receiver reported about 50%. The NICs were both fiber SysKonnect 9843's connected back to back.
Normal reno Modular reno
392.77 392.59
393.96 393.66
393.22 393.72
393.12 393.81
392.09 393.37
393.3 393.58
391.81 393.22
393.11 394.1
391.32 393.77
392.94 393.03average 392.76 393.49
stdev 0.79 0.44
-John
Re: [RFC] TCP congestion schedulers
Quoted 6 lines
For the record, here are some benchmarks from an ia64 over GigE. I set the MTU to 564 so it actually stressed the CPU. Numbers are throughput (10^6 bits/sec).
Command line used: netperf -H 192.168.1.3 -l -1000000000 -c -C -v 2.
I so rarely see anyone use the byte count limits for -l - nice to know they still work :)
FWIW, the argument to -l is passed through netperf's "convert()" routine which means you can use K|M|G for powers-of-two kilo, mega and giga; or k|m|g for powers of ten:
netperf -H 192.168.1.3 -l -1g -c -C -v 2
Quoted 17 lines
The sender was a 1-CPU 900 MHz Itanium2. The receiver was a 1-CPU 2.4 GHz Pentium 4. The sender reported over 99% utilization; the receiver reported about 50%. The NICs were both fiber SysKonnect 9843's connected back to back.
Normal reno Modular reno 392.77 392.59 393.96 393.66 393.22 393.72 393.12 393.81 392.09 393.37 393.3 393.58 391.81 393.22 393.11 394.1 391.32 393.77 392.94 393.03
Quoted 2 lines
average 392.76 393.49
stdev 0.79 0.44
Looks like noise. Fair enough.
rick jones
back to trying to figure-out why netperf IPv6 tests and ping6 won't work with local scope addresses but will with global...
Quoted 6 lines · David S. Miller
For the millionth time, you can't just delete the existing sysctls. That is a user visisble interface.
Instead, you have to make them at least appear to select a single congestion control algorithm
[..]
Maybe this could be a starting point.
This version of hybla patch makes our sysctls mutually exclusive by switching all off just before performing a "write" operation on one of them.
However, there should be more than one cleaner way to do it ...
Signature · 2 lines
Daniele Lacamera root at danielinux.net
Documentation/networking/ip-sysctl.txt +12 -0
@@ -349,6 +349,18 @@ window. Allows two flows sharing the same connection to converge more rapidly. Default: 1 + +tcp_hybla - BOOLEAN + Enable TCP-Hybla congestion control algorithm. + TCP-Hybla is a sender-side only change that eliminates penalization of + long-RTT, large-bandwidth connections, like when satellite legs are + involved, expecially when sharing a common bottleneck with normal + terrestrial connections. + Default: 0 + +tcp_hybla_rtt0 - INTEGER + Divisor to set up rtt0 value for hybla congestion control. + Default: 40 (= 1/40 sec == 25ms) tcp_default_win_scale - INTEGER Sets the minimum window scale TCP will negotiate for on all
include/linux/sysctl.h +4 -0
@@ -344,6 +344,8 @@NET_TCP_DEFAULT_WIN_SCALE =105 ,NET_TCP_MODERATE_RCVBUF =106 ,NET_TCP_TSO_WIN_DIVISOR =107 , +NET_TCP_HYBLA =108 , + NET_TCP_HYBLA_RTT0=109, }; enum {
@@ -788,6 +790,8 @@ void __user *, size_t *, loff_t *);extern int proc_dointvec (ctl_table *,int ,struct file *,void __user *,size_t *,loff_t *); +extern int proc_switch_congctl (ctl_table *,int ,struct file *, +void __user *,size_t *,loff_t *);extern int proc_dointvec_bset (ctl_table *,int ,struct file *,void __user *,size_t *,loff_t *); extern int proc_dointvec_minmax(ctl_table *, int, struct file *,
include/linux/tcp.h +10 -0
@@ -434,6 +434,16 @@__u32 last_cwnd;/* the last snd_cwnd */ __u32 last_stamp;/* time when updated last_cwnd */ } bictcp; + +/* Tcp Hybla structure. */ +struct { +__u32 snd_cwnd_cents;/* Keeps increment values when it is <1, <<7 */ +__u32 rho;/* Rho parameter, integer part */ +__u32 rho2;/* Rho * Rho, integer part */ +__u32 rho_3ls;/* Rho parameter, <<3 */ +__u32 rho2_7ls;/* Rho^2, <<7 */ +__u32 minrtt;/* Minimum smoothed round trip time value seen */ + } hybla; };static inline struct tcp_sock *tcp_sk (const struct sock *sk)
include/net/tcp.h +35 -0
@@ -608,6 +608,8 @@extern int sysctl_tcp_bic_low_window;extern int sysctl_tcp_moderate_rcvbuf;extern int sysctl_tcp_tso_win_divisor; +extern int sysctl_tcp_hybla; +extern int sysctl_tcp_hybla_rtt0;extern atomic_t tcp_memory_allocated;extern atomic_t tcp_sockets_allocated;
@@ -2017,4 +2019,37 @@ return (cwnd != 0); } + +/* +* TCP HYBLA Functions and constants +*/ +/* Hybla reference round trip time (default= 1/40 sec = 25 ms), expressed in jiffies */ +#define RTT0 (__u32) ((HZ/sysctl_tcp_hybla_rtt0)) +/* +* This is called in tcp_ipv4.c and +* tcp_minisocks.c when connection starts +*/ +static inline void init_hybla (struct tcp_sock *tp) +{ + tp->hybla.rho =0 ; + tp->hybla.rho2 =0 ; + tp->hybla.rho_3ls =0 ; + tp->hybla.rho2_7ls =0 ; + tp->hybla.snd_cwnd_cents =0 ; +} +/* This is called to refresh values for hybla parameters */ +static inline void hybla_recalc_param (struct tcp_sock *tp) +{ + + tp->hybla.rho_3ls = (tp->srtt /RTT0 ); +if (tp->hybla.rho_3ls <8 ) + tp->hybla.rho_3ls =8 ; + + tp->hybla.rho=(tp->hybla.rho_3ls >>3 ); + tp->hybla.rho2_7ls = ((tp->hybla.rho_3ls * tp->hybla.rho_3ls)<<1 ); + tp->hybla.rho2=(tp->hybla.rho2_7ls >>7 ); + +if (sysctl_tcp_hybla) + tp->snd_cwnd_clamp =min_t (__u32, tp->snd_cwnd_clamp, tp->hybla.rho<<16 ); +}#endif /* _TCP_H */
kernel/sysctl.c +23 -0
@@ -66,6 +66,11 @@extern int printk_ratelimit_burst;extern int pid_max_min, pid_max_max; +extern int sysctl_tcp_vegas_cong_avoid; +extern int sysctl_tcp_bic; +extern int sysctl_tcp_westwood; +extern int sysctl_tcp_hybla; +#if defined(CONFIG_X86_LOCAL_APIC ) && defined(CONFIG_X86 )int unknown_nmi_panic; extern int proc_unknown_nmi_panic(ctl_table *, int, struct file *,
@@ -1595,6 +1600,23 @@ NULL,NULL); } +/** +* Used by tcp engine to realize a multi-switch for congestion +* control algorithm selection. +*/ +int proc_switch_congctl (ctl_table *table,int write,struct file *filp, +void __user *buffer,size_t *lenp,loff_t *ppos) +{ +if (write){ + sysctl_tcp_vegas_cong_avoid=0 ; + sysctl_tcp_westwood=0 ; + sysctl_tcp_bic=0 ; + sysctl_tcp_hybla=0 ; + } +return do_proc_dointvec (table,write,filp,buffer,lenp,ppos, +NULL ,NULL ); +} +#define OP_SET 0#define OP_AND 1#define OP_OR 2
@@ -2216,6 +2238,7 @@* exception granted :-) */ EXPORT_SYMBOL (proc_dointvec); +EXPORT_SYMBOL (proc_switch_congctl);EXPORT_SYMBOL (proc_dointvec_jiffies);EXPORT_SYMBOL (proc_dointvec_minmax);EXPORT_SYMBOL (proc_dointvec_userhz_jiffies);
net/ipv4/sysctl_net_ipv4.c +19 -3
@@ -608,7 +608,7 @@ .data = &sysctl_tcp_westwood, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec, + .proc_handler = &proc_switch_congctl, }, { .ctl_name = NET_TCP_VEGAS,
@@ -616,7 +616,7 @@ .data = &sysctl_tcp_vegas_cong_avoid, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec, + .proc_handler = &proc_switch_congctl, }, { .ctl_name = NET_TCP_VEGAS_ALPHA,
@@ -648,7 +648,7 @@ .data = &sysctl_tcp_bic, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec, + .proc_handler = &proc_switch_congctl, }, { .ctl_name = NET_TCP_BIC_FAST_CONVERGENCE,
@@ -682,6 +682,22 @@ .mode = 0644, .proc_handler = &proc_dointvec, }, + { + .ctl_name = NET_TCP_HYBLA, + .procname = "tcp_hybla", + .data = &sysctl_tcp_hybla, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_switch_congctl, + }, + { + .ctl_name = NET_TCP_HYBLA_RTT0, + .procname = "tcp_hybla_rtt0", + .data = &sysctl_tcp_hybla_rtt0, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, { .ctl_name = 0 } };
net/ipv4/tcp.c +4 -0
@@ -1813,6 +1813,10 @@if (!(sk->sk_userlocks &SOCK_BINDADDR_LOCK ))inet_reset_saddr (sk); + +/* [TCP HYBLA] Reset values on disconnect */ +if (sysctl_tcp_hybla) +init_hybla (tp); sk->sk_shutdown =0 ;sock_reset_flag (sk,SOCK_DONE );
net/ipv4/tcp_input.c +177 -3
219 lines not on this page · raw message
net/ipv4/tcp_ipv4.c +3 -0
@@ -2055,6 +2055,9 @@* efficiently to them. -DaveM */ tp->snd_cwnd =2 ; + +/* Reset hybla parameters on socket initialization. */ +init_hybla (tp);/* See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values.
net/ipv4/tcp_minisocks.c +3 -0
@@ -784,6 +784,9 @@ newtp->dsack =0 ; newtp->eff_sacks =0 ; + +/* Reset hybla parameters on socket initialization. */ +init_hybla (newtp); newtp->probes_out =0 ; newtp->num_sacks =0 ;