diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2005-06-23 15:19:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-06-23 15:19:55 -0400 |
commit | 317a76f9a44b437d6301718f4e5d08bd93f98da7 (patch) | |
tree | caeba9839dee264f59b035b81c3d13d6c61b638e /net/ipv4/tcp_output.c | |
parent | a8ad86f2dc46356f87be1327dabc18bdbda32f50 (diff) |
[TCP]: Add pluggable congestion control algorithm infrastructure.
Allow TCP to have multiple pluggable congestion control algorithms.
Algorithms are defined by a set of operations and can be built in
or modules. The legacy "new RENO" algorithm is used as a starting
point and fallback.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 23 |
1 files changed, 8 insertions, 15 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f17c6577e337..0e17c244875c 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -111,8 +111,7 @@ static void tcp_cwnd_restart(struct tcp_sock *tp, struct dst_entry *dst) | |||
111 | u32 restart_cwnd = tcp_init_cwnd(tp, dst); | 111 | u32 restart_cwnd = tcp_init_cwnd(tp, dst); |
112 | u32 cwnd = tp->snd_cwnd; | 112 | u32 cwnd = tp->snd_cwnd; |
113 | 113 | ||
114 | if (tcp_is_vegas(tp)) | 114 | tcp_ca_event(tp, CA_EVENT_CWND_RESTART); |
115 | tcp_vegas_enable(tp); | ||
116 | 115 | ||
117 | tp->snd_ssthresh = tcp_current_ssthresh(tp); | 116 | tp->snd_ssthresh = tcp_current_ssthresh(tp); |
118 | restart_cwnd = min(restart_cwnd, cwnd); | 117 | restart_cwnd = min(restart_cwnd, cwnd); |
@@ -280,6 +279,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
280 | #define SYSCTL_FLAG_WSCALE 0x2 | 279 | #define SYSCTL_FLAG_WSCALE 0x2 |
281 | #define SYSCTL_FLAG_SACK 0x4 | 280 | #define SYSCTL_FLAG_SACK 0x4 |
282 | 281 | ||
282 | /* If congestion control is doing timestamping */ | ||
283 | if (tp->ca_ops->rtt_sample) | ||
284 | do_gettimeofday(&skb->stamp); | ||
285 | |||
283 | sysctl_flags = 0; | 286 | sysctl_flags = 0; |
284 | if (tcb->flags & TCPCB_FLAG_SYN) { | 287 | if (tcb->flags & TCPCB_FLAG_SYN) { |
285 | tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS; | 288 | tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS; |
@@ -304,17 +307,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
304 | (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); | 307 | (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); |
305 | } | 308 | } |
306 | 309 | ||
307 | /* | 310 | if (tcp_packets_in_flight(tp) == 0) |
308 | * If the connection is idle and we are restarting, | 311 | tcp_ca_event(tp, CA_EVENT_TX_START); |
309 | * then we don't want to do any Vegas calculations | ||
310 | * until we get fresh RTT samples. So when we | ||
311 | * restart, we reset our Vegas state to a clean | ||
312 | * slate. After we get acks for this flight of | ||
313 | * packets, _then_ we can make Vegas calculations | ||
314 | * again. | ||
315 | */ | ||
316 | if (tcp_is_vegas(tp) && tcp_packets_in_flight(tp) == 0) | ||
317 | tcp_vegas_enable(tp); | ||
318 | 312 | ||
319 | th = (struct tcphdr *) skb_push(skb, tcp_header_size); | 313 | th = (struct tcphdr *) skb_push(skb, tcp_header_size); |
320 | skb->h.th = th; | 314 | skb->h.th = th; |
@@ -521,6 +515,7 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len) | |||
521 | * skbs, which it never sent before. --ANK | 515 | * skbs, which it never sent before. --ANK |
522 | */ | 516 | */ |
523 | TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when; | 517 | TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when; |
518 | buff->stamp = skb->stamp; | ||
524 | 519 | ||
525 | if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) { | 520 | if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) { |
526 | tp->lost_out -= tcp_skb_pcount(skb); | 521 | tp->lost_out -= tcp_skb_pcount(skb); |
@@ -1449,7 +1444,6 @@ static inline void tcp_connect_init(struct sock *sk) | |||
1449 | tp->window_clamp = dst_metric(dst, RTAX_WINDOW); | 1444 | tp->window_clamp = dst_metric(dst, RTAX_WINDOW); |
1450 | tp->advmss = dst_metric(dst, RTAX_ADVMSS); | 1445 | tp->advmss = dst_metric(dst, RTAX_ADVMSS); |
1451 | tcp_initialize_rcv_mss(sk); | 1446 | tcp_initialize_rcv_mss(sk); |
1452 | tcp_ca_init(tp); | ||
1453 | 1447 | ||
1454 | tcp_select_initial_window(tcp_full_space(sk), | 1448 | tcp_select_initial_window(tcp_full_space(sk), |
1455 | tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), | 1449 | tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), |
@@ -1503,7 +1497,6 @@ int tcp_connect(struct sock *sk) | |||
1503 | TCP_SKB_CB(buff)->end_seq = tp->write_seq; | 1497 | TCP_SKB_CB(buff)->end_seq = tp->write_seq; |
1504 | tp->snd_nxt = tp->write_seq; | 1498 | tp->snd_nxt = tp->write_seq; |
1505 | tp->pushed_seq = tp->write_seq; | 1499 | tp->pushed_seq = tp->write_seq; |
1506 | tcp_ca_init(tp); | ||
1507 | 1500 | ||
1508 | /* Send it off. */ | 1501 | /* Send it off. */ |
1509 | TCP_SKB_CB(buff)->when = tcp_time_stamp; | 1502 | TCP_SKB_CB(buff)->when = tcp_time_stamp; |