diff options
author | Stephen Hemminger <shemminger@linux-foundation.org> | 2007-04-24 01:26:16 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 01:29:45 -0400 |
commit | 164891aadf1721fca4dce473bb0e0998181537c6 (patch) | |
tree | 991393ec7306da475cb306fcc7cb084f737ebadc | |
parent | 65d1b4a7e73fe0e1f5275ad7d2d3547981480886 (diff) |
[TCP]: Congestion control API update.
Do some simple changes to make congestion control API faster/cleaner.
* use ktime_t rather than timeval
* merge rtt sampling into existing ack callback
this means one indirect call versus two per ack.
* use flags bits to store options/settings
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/skbuff.h | 5 | ||||
-rw-r--r-- | include/net/tcp.h | 9 | ||||
-rw-r--r-- | net/ipv4/tcp_bic.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_cong.c | 14 | ||||
-rw-r--r-- | net/ipv4/tcp_cubic.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_htcp.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_illinois.c | 16 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 25 | ||||
-rw-r--r-- | net/ipv4/tcp_lp.c | 8 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_vegas.c | 10 | ||||
-rw-r--r-- | net/ipv4/tcp_veno.c | 10 | ||||
-rw-r--r-- | net/ipv4/tcp_westwood.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_yeah.c | 6 | ||||
-rw-r--r-- | net/ipv4/tcp_yeah.h | 7 |
15 files changed, 65 insertions, 55 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 50f6f6a094cf..2694cb3ca763 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -1569,6 +1569,11 @@ static inline void __net_timestamp(struct sk_buff *skb) | |||
1569 | skb->tstamp = ktime_get_real(); | 1569 | skb->tstamp = ktime_get_real(); |
1570 | } | 1570 | } |
1571 | 1571 | ||
1572 | static inline ktime_t net_timedelta(ktime_t t) | ||
1573 | { | ||
1574 | return ktime_sub(ktime_get_real(), t); | ||
1575 | } | ||
1576 | |||
1572 | 1577 | ||
1573 | extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len); | 1578 | extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len); |
1574 | extern __sum16 __skb_checksum_complete(struct sk_buff *skb); | 1579 | extern __sum16 __skb_checksum_complete(struct sk_buff *skb); |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 43910fe3c448..a385797f160a 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -629,9 +629,12 @@ enum tcp_ca_event { | |||
629 | #define TCP_CA_MAX 128 | 629 | #define TCP_CA_MAX 128 |
630 | #define TCP_CA_BUF_MAX (TCP_CA_NAME_MAX*TCP_CA_MAX) | 630 | #define TCP_CA_BUF_MAX (TCP_CA_NAME_MAX*TCP_CA_MAX) |
631 | 631 | ||
632 | #define TCP_CONG_NON_RESTRICTED 0x1 | ||
633 | #define TCP_CONG_RTT_STAMP 0x2 | ||
634 | |||
632 | struct tcp_congestion_ops { | 635 | struct tcp_congestion_ops { |
633 | struct list_head list; | 636 | struct list_head list; |
634 | int non_restricted; | 637 | unsigned long flags; |
635 | 638 | ||
636 | /* initialize private data (optional) */ | 639 | /* initialize private data (optional) */ |
637 | void (*init)(struct sock *sk); | 640 | void (*init)(struct sock *sk); |
@@ -645,8 +648,6 @@ struct tcp_congestion_ops { | |||
645 | /* do new cwnd calculation (required) */ | 648 | /* do new cwnd calculation (required) */ |
646 | void (*cong_avoid)(struct sock *sk, u32 ack, | 649 | void (*cong_avoid)(struct sock *sk, u32 ack, |
647 | u32 rtt, u32 in_flight, int good_ack); | 650 | u32 rtt, u32 in_flight, int good_ack); |
648 | /* round trip time sample per acked packet (optional) */ | ||
649 | void (*rtt_sample)(struct sock *sk, u32 usrtt); | ||
650 | /* call before changing ca_state (optional) */ | 651 | /* call before changing ca_state (optional) */ |
651 | void (*set_state)(struct sock *sk, u8 new_state); | 652 | void (*set_state)(struct sock *sk, u8 new_state); |
652 | /* call when cwnd event occurs (optional) */ | 653 | /* call when cwnd event occurs (optional) */ |
@@ -654,7 +655,7 @@ struct tcp_congestion_ops { | |||
654 | /* new value of cwnd after loss (optional) */ | 655 | /* new value of cwnd after loss (optional) */ |
655 | u32 (*undo_cwnd)(struct sock *sk); | 656 | u32 (*undo_cwnd)(struct sock *sk); |
656 | /* hook for packet ack accounting (optional) */ | 657 | /* hook for packet ack accounting (optional) */ |
657 | void (*pkts_acked)(struct sock *sk, u32 num_acked); | 658 | void (*pkts_acked)(struct sock *sk, u32 num_acked, ktime_t last); |
658 | /* get info for inet_diag (optional) */ | 659 | /* get info for inet_diag (optional) */ |
659 | void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb); | 660 | void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb); |
660 | 661 | ||
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c index 5730333cd0ac..281c9f913257 100644 --- a/net/ipv4/tcp_bic.c +++ b/net/ipv4/tcp_bic.c | |||
@@ -206,7 +206,7 @@ static void bictcp_state(struct sock *sk, u8 new_state) | |||
206 | /* Track delayed acknowledgment ratio using sliding window | 206 | /* Track delayed acknowledgment ratio using sliding window |
207 | * ratio = (15*ratio + sample) / 16 | 207 | * ratio = (15*ratio + sample) / 16 |
208 | */ | 208 | */ |
209 | static void bictcp_acked(struct sock *sk, u32 cnt) | 209 | static void bictcp_acked(struct sock *sk, u32 cnt, ktime_t last) |
210 | { | 210 | { |
211 | const struct inet_connection_sock *icsk = inet_csk(sk); | 211 | const struct inet_connection_sock *icsk = inet_csk(sk); |
212 | 212 | ||
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index ccd88407e0cd..86b26539e54b 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -126,7 +126,7 @@ int tcp_set_default_congestion_control(const char *name) | |||
126 | #endif | 126 | #endif |
127 | 127 | ||
128 | if (ca) { | 128 | if (ca) { |
129 | ca->non_restricted = 1; /* default is always allowed */ | 129 | ca->flags |= TCP_CONG_NON_RESTRICTED; /* default is always allowed */ |
130 | list_move(&ca->list, &tcp_cong_list); | 130 | list_move(&ca->list, &tcp_cong_list); |
131 | ret = 0; | 131 | ret = 0; |
132 | } | 132 | } |
@@ -181,7 +181,7 @@ void tcp_get_allowed_congestion_control(char *buf, size_t maxlen) | |||
181 | *buf = '\0'; | 181 | *buf = '\0'; |
182 | rcu_read_lock(); | 182 | rcu_read_lock(); |
183 | list_for_each_entry_rcu(ca, &tcp_cong_list, list) { | 183 | list_for_each_entry_rcu(ca, &tcp_cong_list, list) { |
184 | if (!ca->non_restricted) | 184 | if (!(ca->flags & TCP_CONG_NON_RESTRICTED)) |
185 | continue; | 185 | continue; |
186 | offs += snprintf(buf + offs, maxlen - offs, | 186 | offs += snprintf(buf + offs, maxlen - offs, |
187 | "%s%s", | 187 | "%s%s", |
@@ -212,16 +212,16 @@ int tcp_set_allowed_congestion_control(char *val) | |||
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | /* pass 2 clear */ | 215 | /* pass 2 clear old values */ |
216 | list_for_each_entry_rcu(ca, &tcp_cong_list, list) | 216 | list_for_each_entry_rcu(ca, &tcp_cong_list, list) |
217 | ca->non_restricted = 0; | 217 | ca->flags &= ~TCP_CONG_NON_RESTRICTED; |
218 | 218 | ||
219 | /* pass 3 mark as allowed */ | 219 | /* pass 3 mark as allowed */ |
220 | while ((name = strsep(&val, " ")) && *name) { | 220 | while ((name = strsep(&val, " ")) && *name) { |
221 | ca = tcp_ca_find(name); | 221 | ca = tcp_ca_find(name); |
222 | WARN_ON(!ca); | 222 | WARN_ON(!ca); |
223 | if (ca) | 223 | if (ca) |
224 | ca->non_restricted = 1; | 224 | ca->flags |= TCP_CONG_NON_RESTRICTED; |
225 | } | 225 | } |
226 | out: | 226 | out: |
227 | spin_unlock(&tcp_cong_list_lock); | 227 | spin_unlock(&tcp_cong_list_lock); |
@@ -256,7 +256,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
256 | if (!ca) | 256 | if (!ca) |
257 | err = -ENOENT; | 257 | err = -ENOENT; |
258 | 258 | ||
259 | else if (!(ca->non_restricted || capable(CAP_NET_ADMIN))) | 259 | else if (!((ca->flags & TCP_CONG_NON_RESTRICTED) || capable(CAP_NET_ADMIN))) |
260 | err = -EPERM; | 260 | err = -EPERM; |
261 | 261 | ||
262 | else if (!try_module_get(ca->owner)) | 262 | else if (!try_module_get(ca->owner)) |
@@ -371,8 +371,8 @@ u32 tcp_reno_min_cwnd(const struct sock *sk) | |||
371 | EXPORT_SYMBOL_GPL(tcp_reno_min_cwnd); | 371 | EXPORT_SYMBOL_GPL(tcp_reno_min_cwnd); |
372 | 372 | ||
373 | struct tcp_congestion_ops tcp_reno = { | 373 | struct tcp_congestion_ops tcp_reno = { |
374 | .flags = TCP_CONG_NON_RESTRICTED, | ||
374 | .name = "reno", | 375 | .name = "reno", |
375 | .non_restricted = 1, | ||
376 | .owner = THIS_MODULE, | 376 | .owner = THIS_MODULE, |
377 | .ssthresh = tcp_reno_ssthresh, | 377 | .ssthresh = tcp_reno_ssthresh, |
378 | .cong_avoid = tcp_reno_cong_avoid, | 378 | .cong_avoid = tcp_reno_cong_avoid, |
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index 296845be912b..14224487b16b 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c | |||
@@ -334,7 +334,7 @@ static void bictcp_state(struct sock *sk, u8 new_state) | |||
334 | /* Track delayed acknowledgment ratio using sliding window | 334 | /* Track delayed acknowledgment ratio using sliding window |
335 | * ratio = (15*ratio + sample) / 16 | 335 | * ratio = (15*ratio + sample) / 16 |
336 | */ | 336 | */ |
337 | static void bictcp_acked(struct sock *sk, u32 cnt) | 337 | static void bictcp_acked(struct sock *sk, u32 cnt, ktime_t last) |
338 | { | 338 | { |
339 | const struct inet_connection_sock *icsk = inet_csk(sk); | 339 | const struct inet_connection_sock *icsk = inet_csk(sk); |
340 | 340 | ||
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c index 1020eb48d8d1..4ba4a7ae0a85 100644 --- a/net/ipv4/tcp_htcp.c +++ b/net/ipv4/tcp_htcp.c | |||
@@ -98,7 +98,7 @@ static inline void measure_rtt(struct sock *sk) | |||
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked) | 101 | static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked, ktime_t last) |
102 | { | 102 | { |
103 | const struct inet_connection_sock *icsk = inet_csk(sk); | 103 | const struct inet_connection_sock *icsk = inet_csk(sk); |
104 | const struct tcp_sock *tp = tcp_sk(sk); | 104 | const struct tcp_sock *tp = tcp_sk(sk); |
diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c index ae6298600886..8e3165917f72 100644 --- a/net/ipv4/tcp_illinois.c +++ b/net/ipv4/tcp_illinois.c | |||
@@ -83,9 +83,14 @@ static void tcp_illinois_init(struct sock *sk) | |||
83 | } | 83 | } |
84 | 84 | ||
85 | /* Measure RTT for each ack. */ | 85 | /* Measure RTT for each ack. */ |
86 | static void tcp_illinois_rtt_sample(struct sock *sk, u32 rtt) | 86 | static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, ktime_t last) |
87 | { | 87 | { |
88 | struct illinois *ca = inet_csk_ca(sk); | 88 | struct illinois *ca = inet_csk_ca(sk); |
89 | u32 rtt; | ||
90 | |||
91 | ca->acked = pkts_acked; | ||
92 | |||
93 | rtt = ktime_to_ns(net_timedelta(last)) / NSEC_PER_USEC; | ||
89 | 94 | ||
90 | /* ignore bogus values, this prevents wraparound in alpha math */ | 95 | /* ignore bogus values, this prevents wraparound in alpha math */ |
91 | if (rtt > RTT_MAX) | 96 | if (rtt > RTT_MAX) |
@@ -103,13 +108,6 @@ static void tcp_illinois_rtt_sample(struct sock *sk, u32 rtt) | |||
103 | ca->sum_rtt += rtt; | 108 | ca->sum_rtt += rtt; |
104 | } | 109 | } |
105 | 110 | ||
106 | /* Capture count of packets covered by ack, to adjust for delayed acks */ | ||
107 | static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked) | ||
108 | { | ||
109 | struct illinois *ca = inet_csk_ca(sk); | ||
110 | ca->acked = pkts_acked; | ||
111 | } | ||
112 | |||
113 | /* Maximum queuing delay */ | 111 | /* Maximum queuing delay */ |
114 | static inline u32 max_delay(const struct illinois *ca) | 112 | static inline u32 max_delay(const struct illinois *ca) |
115 | { | 113 | { |
@@ -325,12 +323,12 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, | |||
325 | } | 323 | } |
326 | 324 | ||
327 | static struct tcp_congestion_ops tcp_illinois = { | 325 | static struct tcp_congestion_ops tcp_illinois = { |
326 | .flags = TCP_CONG_RTT_STAMP, | ||
328 | .init = tcp_illinois_init, | 327 | .init = tcp_illinois_init, |
329 | .ssthresh = tcp_illinois_ssthresh, | 328 | .ssthresh = tcp_illinois_ssthresh, |
330 | .min_cwnd = tcp_reno_min_cwnd, | 329 | .min_cwnd = tcp_reno_min_cwnd, |
331 | .cong_avoid = tcp_illinois_cong_avoid, | 330 | .cong_avoid = tcp_illinois_cong_avoid, |
332 | .set_state = tcp_illinois_state, | 331 | .set_state = tcp_illinois_state, |
333 | .rtt_sample = tcp_illinois_rtt_sample, | ||
334 | .get_info = tcp_illinois_info, | 332 | .get_info = tcp_illinois_info, |
335 | .pkts_acked = tcp_illinois_acked, | 333 | .pkts_acked = tcp_illinois_acked, |
336 | 334 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 633389390788..051f0f815f17 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -2402,14 +2402,6 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb, | |||
2402 | return acked; | 2402 | return acked; |
2403 | } | 2403 | } |
2404 | 2404 | ||
2405 | static u32 tcp_usrtt(struct timeval *tv) | ||
2406 | { | ||
2407 | struct timeval now; | ||
2408 | |||
2409 | do_gettimeofday(&now); | ||
2410 | return (now.tv_sec - tv->tv_sec) * 1000000 + (now.tv_usec - tv->tv_usec); | ||
2411 | } | ||
2412 | |||
2413 | /* Remove acknowledged frames from the retransmission queue. */ | 2405 | /* Remove acknowledged frames from the retransmission queue. */ |
2414 | static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) | 2406 | static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) |
2415 | { | 2407 | { |
@@ -2420,9 +2412,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) | |||
2420 | int acked = 0; | 2412 | int acked = 0; |
2421 | __s32 seq_rtt = -1; | 2413 | __s32 seq_rtt = -1; |
2422 | u32 pkts_acked = 0; | 2414 | u32 pkts_acked = 0; |
2423 | void (*rtt_sample)(struct sock *sk, u32 usrtt) | 2415 | ktime_t last_ackt = ktime_set(0,0); |
2424 | = icsk->icsk_ca_ops->rtt_sample; | ||
2425 | struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; | ||
2426 | 2416 | ||
2427 | while ((skb = tcp_write_queue_head(sk)) && | 2417 | while ((skb = tcp_write_queue_head(sk)) && |
2428 | skb != tcp_send_head(sk)) { | 2418 | skb != tcp_send_head(sk)) { |
@@ -2471,7 +2461,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) | |||
2471 | seq_rtt = -1; | 2461 | seq_rtt = -1; |
2472 | } else if (seq_rtt < 0) { | 2462 | } else if (seq_rtt < 0) { |
2473 | seq_rtt = now - scb->when; | 2463 | seq_rtt = now - scb->when; |
2474 | skb_get_timestamp(skb, &tv); | 2464 | last_ackt = skb->tstamp; |
2475 | } | 2465 | } |
2476 | if (sacked & TCPCB_SACKED_ACKED) | 2466 | if (sacked & TCPCB_SACKED_ACKED) |
2477 | tp->sacked_out -= tcp_skb_pcount(skb); | 2467 | tp->sacked_out -= tcp_skb_pcount(skb); |
@@ -2484,7 +2474,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) | |||
2484 | } | 2474 | } |
2485 | } else if (seq_rtt < 0) { | 2475 | } else if (seq_rtt < 0) { |
2486 | seq_rtt = now - scb->when; | 2476 | seq_rtt = now - scb->when; |
2487 | skb_get_timestamp(skb, &tv); | 2477 | last_ackt = skb->tstamp; |
2488 | } | 2478 | } |
2489 | tcp_dec_pcount_approx(&tp->fackets_out, skb); | 2479 | tcp_dec_pcount_approx(&tp->fackets_out, skb); |
2490 | tcp_packets_out_dec(tp, skb); | 2480 | tcp_packets_out_dec(tp, skb); |
@@ -2494,13 +2484,14 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) | |||
2494 | } | 2484 | } |
2495 | 2485 | ||
2496 | if (acked&FLAG_ACKED) { | 2486 | if (acked&FLAG_ACKED) { |
2487 | const struct tcp_congestion_ops *ca_ops | ||
2488 | = inet_csk(sk)->icsk_ca_ops; | ||
2489 | |||
2497 | tcp_ack_update_rtt(sk, acked, seq_rtt); | 2490 | tcp_ack_update_rtt(sk, acked, seq_rtt); |
2498 | tcp_ack_packets_out(sk); | 2491 | tcp_ack_packets_out(sk); |
2499 | if (rtt_sample && !(acked & FLAG_RETRANS_DATA_ACKED)) | ||
2500 | (*rtt_sample)(sk, tcp_usrtt(&tv)); | ||
2501 | 2492 | ||
2502 | if (icsk->icsk_ca_ops->pkts_acked) | 2493 | if (ca_ops->pkts_acked) |
2503 | icsk->icsk_ca_ops->pkts_acked(sk, pkts_acked); | 2494 | ca_ops->pkts_acked(sk, pkts_acked, last_ackt); |
2504 | } | 2495 | } |
2505 | 2496 | ||
2506 | #if FASTRETRANS_DEBUG > 0 | 2497 | #if FASTRETRANS_DEBUG > 0 |
diff --git a/net/ipv4/tcp_lp.c b/net/ipv4/tcp_lp.c index f0ebaf0e21cb..b4e062ab24a1 100644 --- a/net/ipv4/tcp_lp.c +++ b/net/ipv4/tcp_lp.c | |||
@@ -218,7 +218,7 @@ static u32 tcp_lp_owd_calculator(struct sock *sk) | |||
218 | * 3. calc smoothed OWD (SOWD). | 218 | * 3. calc smoothed OWD (SOWD). |
219 | * Most ideas come from the original TCP-LP implementation. | 219 | * Most ideas come from the original TCP-LP implementation. |
220 | */ | 220 | */ |
221 | static void tcp_lp_rtt_sample(struct sock *sk, u32 usrtt) | 221 | static void tcp_lp_rtt_sample(struct sock *sk, u32 rtt) |
222 | { | 222 | { |
223 | struct lp *lp = inet_csk_ca(sk); | 223 | struct lp *lp = inet_csk_ca(sk); |
224 | s64 mowd = tcp_lp_owd_calculator(sk); | 224 | s64 mowd = tcp_lp_owd_calculator(sk); |
@@ -261,11 +261,13 @@ static void tcp_lp_rtt_sample(struct sock *sk, u32 usrtt) | |||
261 | * newReno in increase case. | 261 | * newReno in increase case. |
262 | * We work it out by following the idea from TCP-LP's paper directly | 262 | * We work it out by following the idea from TCP-LP's paper directly |
263 | */ | 263 | */ |
264 | static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked) | 264 | static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, ktime_t last) |
265 | { | 265 | { |
266 | struct tcp_sock *tp = tcp_sk(sk); | 266 | struct tcp_sock *tp = tcp_sk(sk); |
267 | struct lp *lp = inet_csk_ca(sk); | 267 | struct lp *lp = inet_csk_ca(sk); |
268 | 268 | ||
269 | tcp_lp_rtt_sample(sk, ktime_to_ns(net_timedelta(last)) / NSEC_PER_USEC); | ||
270 | |||
269 | /* calc inference */ | 271 | /* calc inference */ |
270 | if (tcp_time_stamp > tp->rx_opt.rcv_tsecr) | 272 | if (tcp_time_stamp > tp->rx_opt.rcv_tsecr) |
271 | lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr); | 273 | lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr); |
@@ -312,11 +314,11 @@ static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked) | |||
312 | } | 314 | } |
313 | 315 | ||
314 | static struct tcp_congestion_ops tcp_lp = { | 316 | static struct tcp_congestion_ops tcp_lp = { |
317 | .flags = TCP_CONG_RTT_STAMP, | ||
315 | .init = tcp_lp_init, | 318 | .init = tcp_lp_init, |
316 | .ssthresh = tcp_reno_ssthresh, | 319 | .ssthresh = tcp_reno_ssthresh, |
317 | .cong_avoid = tcp_lp_cong_avoid, | 320 | .cong_avoid = tcp_lp_cong_avoid, |
318 | .min_cwnd = tcp_reno_min_cwnd, | 321 | .min_cwnd = tcp_reno_min_cwnd, |
319 | .rtt_sample = tcp_lp_rtt_sample, | ||
320 | .pkts_acked = tcp_lp_pkts_acked, | 322 | .pkts_acked = tcp_lp_pkts_acked, |
321 | 323 | ||
322 | .owner = THIS_MODULE, | 324 | .owner = THIS_MODULE, |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 3a60aea744ae..e70a6840cb64 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -409,7 +409,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
409 | /* If congestion control is doing timestamping, we must | 409 | /* If congestion control is doing timestamping, we must |
410 | * take such a timestamp before we potentially clone/copy. | 410 | * take such a timestamp before we potentially clone/copy. |
411 | */ | 411 | */ |
412 | if (icsk->icsk_ca_ops->rtt_sample) | 412 | if (icsk->icsk_ca_ops->flags & TCP_CONG_RTT_STAMP) |
413 | __net_timestamp(skb); | 413 | __net_timestamp(skb); |
414 | 414 | ||
415 | if (likely(clone_it)) { | 415 | if (likely(clone_it)) { |
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c index 87e72bef6d08..f4104eeb5f26 100644 --- a/net/ipv4/tcp_vegas.c +++ b/net/ipv4/tcp_vegas.c | |||
@@ -120,10 +120,13 @@ static void tcp_vegas_init(struct sock *sk) | |||
120 | * o min-filter RTT samples from a much longer window (forever for now) | 120 | * o min-filter RTT samples from a much longer window (forever for now) |
121 | * to find the propagation delay (baseRTT) | 121 | * to find the propagation delay (baseRTT) |
122 | */ | 122 | */ |
123 | static void tcp_vegas_rtt_calc(struct sock *sk, u32 usrtt) | 123 | static void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) |
124 | { | 124 | { |
125 | struct vegas *vegas = inet_csk_ca(sk); | 125 | struct vegas *vegas = inet_csk_ca(sk); |
126 | u32 vrtt = usrtt + 1; /* Never allow zero rtt or baseRTT */ | 126 | u32 vrtt; |
127 | |||
128 | /* Never allow zero rtt or baseRTT */ | ||
129 | vrtt = (ktime_to_ns(net_timedelta(last)) / NSEC_PER_USEC) + 1; | ||
127 | 130 | ||
128 | /* Filter to find propagation delay: */ | 131 | /* Filter to find propagation delay: */ |
129 | if (vrtt < vegas->baseRTT) | 132 | if (vrtt < vegas->baseRTT) |
@@ -353,11 +356,12 @@ static void tcp_vegas_get_info(struct sock *sk, u32 ext, | |||
353 | } | 356 | } |
354 | 357 | ||
355 | static struct tcp_congestion_ops tcp_vegas = { | 358 | static struct tcp_congestion_ops tcp_vegas = { |
359 | .flags = TCP_CONG_RTT_STAMP, | ||
356 | .init = tcp_vegas_init, | 360 | .init = tcp_vegas_init, |
357 | .ssthresh = tcp_reno_ssthresh, | 361 | .ssthresh = tcp_reno_ssthresh, |
358 | .cong_avoid = tcp_vegas_cong_avoid, | 362 | .cong_avoid = tcp_vegas_cong_avoid, |
359 | .min_cwnd = tcp_reno_min_cwnd, | 363 | .min_cwnd = tcp_reno_min_cwnd, |
360 | .rtt_sample = tcp_vegas_rtt_calc, | 364 | .pkts_acked = tcp_vegas_pkts_acked, |
361 | .set_state = tcp_vegas_state, | 365 | .set_state = tcp_vegas_state, |
362 | .cwnd_event = tcp_vegas_cwnd_event, | 366 | .cwnd_event = tcp_vegas_cwnd_event, |
363 | .get_info = tcp_vegas_get_info, | 367 | .get_info = tcp_vegas_get_info, |
diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c index ce57bf302f6c..0b50d0607a0e 100644 --- a/net/ipv4/tcp_veno.c +++ b/net/ipv4/tcp_veno.c | |||
@@ -69,10 +69,13 @@ static void tcp_veno_init(struct sock *sk) | |||
69 | } | 69 | } |
70 | 70 | ||
71 | /* Do rtt sampling needed for Veno. */ | 71 | /* Do rtt sampling needed for Veno. */ |
72 | static void tcp_veno_rtt_calc(struct sock *sk, u32 usrtt) | 72 | static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) |
73 | { | 73 | { |
74 | struct veno *veno = inet_csk_ca(sk); | 74 | struct veno *veno = inet_csk_ca(sk); |
75 | u32 vrtt = usrtt + 1; /* Never allow zero rtt or basertt */ | 75 | u32 vrtt; |
76 | |||
77 | /* Never allow zero rtt or baseRTT */ | ||
78 | vrtt = (ktime_to_ns(net_timedelta(last)) / NSEC_PER_USEC) + 1; | ||
76 | 79 | ||
77 | /* Filter to find propagation delay: */ | 80 | /* Filter to find propagation delay: */ |
78 | if (vrtt < veno->basertt) | 81 | if (vrtt < veno->basertt) |
@@ -199,10 +202,11 @@ static u32 tcp_veno_ssthresh(struct sock *sk) | |||
199 | } | 202 | } |
200 | 203 | ||
201 | static struct tcp_congestion_ops tcp_veno = { | 204 | static struct tcp_congestion_ops tcp_veno = { |
205 | .flags = TCP_CONG_RTT_STAMP, | ||
202 | .init = tcp_veno_init, | 206 | .init = tcp_veno_init, |
203 | .ssthresh = tcp_veno_ssthresh, | 207 | .ssthresh = tcp_veno_ssthresh, |
204 | .cong_avoid = tcp_veno_cong_avoid, | 208 | .cong_avoid = tcp_veno_cong_avoid, |
205 | .rtt_sample = tcp_veno_rtt_calc, | 209 | .pkts_acked = tcp_veno_pkts_acked, |
206 | .set_state = tcp_veno_state, | 210 | .set_state = tcp_veno_state, |
207 | .cwnd_event = tcp_veno_cwnd_event, | 211 | .cwnd_event = tcp_veno_cwnd_event, |
208 | 212 | ||
diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c index ae1026a67720..e61e09dd513e 100644 --- a/net/ipv4/tcp_westwood.c +++ b/net/ipv4/tcp_westwood.c | |||
@@ -100,7 +100,7 @@ static void westwood_filter(struct westwood *w, u32 delta) | |||
100 | * Called after processing group of packets. | 100 | * Called after processing group of packets. |
101 | * but all westwood needs is the last sample of srtt. | 101 | * but all westwood needs is the last sample of srtt. |
102 | */ | 102 | */ |
103 | static void tcp_westwood_pkts_acked(struct sock *sk, u32 cnt) | 103 | static void tcp_westwood_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) |
104 | { | 104 | { |
105 | struct westwood *w = inet_csk_ca(sk); | 105 | struct westwood *w = inet_csk_ca(sk); |
106 | if (cnt > 0) | 106 | if (cnt > 0) |
diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c index 46dd1bee583a..81ef02c1649a 100644 --- a/net/ipv4/tcp_yeah.c +++ b/net/ipv4/tcp_yeah.c | |||
@@ -64,13 +64,15 @@ static void tcp_yeah_init(struct sock *sk) | |||
64 | } | 64 | } |
65 | 65 | ||
66 | 66 | ||
67 | static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked) | 67 | static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, ktime_t last) |
68 | { | 68 | { |
69 | const struct inet_connection_sock *icsk = inet_csk(sk); | 69 | const struct inet_connection_sock *icsk = inet_csk(sk); |
70 | struct yeah *yeah = inet_csk_ca(sk); | 70 | struct yeah *yeah = inet_csk_ca(sk); |
71 | 71 | ||
72 | if (icsk->icsk_ca_state == TCP_CA_Open) | 72 | if (icsk->icsk_ca_state == TCP_CA_Open) |
73 | yeah->pkts_acked = pkts_acked; | 73 | yeah->pkts_acked = pkts_acked; |
74 | |||
75 | tcp_vegas_pkts_acked(sk, pkts_acked, last); | ||
74 | } | 76 | } |
75 | 77 | ||
76 | static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, | 78 | static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, |
@@ -237,11 +239,11 @@ static u32 tcp_yeah_ssthresh(struct sock *sk) { | |||
237 | } | 239 | } |
238 | 240 | ||
239 | static struct tcp_congestion_ops tcp_yeah = { | 241 | static struct tcp_congestion_ops tcp_yeah = { |
242 | .flags = TCP_CONG_RTT_STAMP, | ||
240 | .init = tcp_yeah_init, | 243 | .init = tcp_yeah_init, |
241 | .ssthresh = tcp_yeah_ssthresh, | 244 | .ssthresh = tcp_yeah_ssthresh, |
242 | .cong_avoid = tcp_yeah_cong_avoid, | 245 | .cong_avoid = tcp_yeah_cong_avoid, |
243 | .min_cwnd = tcp_reno_min_cwnd, | 246 | .min_cwnd = tcp_reno_min_cwnd, |
244 | .rtt_sample = tcp_vegas_rtt_calc, | ||
245 | .set_state = tcp_vegas_state, | 247 | .set_state = tcp_vegas_state, |
246 | .cwnd_event = tcp_vegas_cwnd_event, | 248 | .cwnd_event = tcp_vegas_cwnd_event, |
247 | .get_info = tcp_vegas_get_info, | 249 | .get_info = tcp_vegas_get_info, |
diff --git a/net/ipv4/tcp_yeah.h b/net/ipv4/tcp_yeah.h index a62d82038fd0..33ad5385c188 100644 --- a/net/ipv4/tcp_yeah.h +++ b/net/ipv4/tcp_yeah.h | |||
@@ -81,10 +81,13 @@ static void tcp_vegas_state(struct sock *sk, u8 ca_state) | |||
81 | * o min-filter RTT samples from a much longer window (forever for now) | 81 | * o min-filter RTT samples from a much longer window (forever for now) |
82 | * to find the propagation delay (baseRTT) | 82 | * to find the propagation delay (baseRTT) |
83 | */ | 83 | */ |
84 | static void tcp_vegas_rtt_calc(struct sock *sk, u32 usrtt) | 84 | static void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) |
85 | { | 85 | { |
86 | struct vegas *vegas = inet_csk_ca(sk); | 86 | struct vegas *vegas = inet_csk_ca(sk); |
87 | u32 vrtt = usrtt + 1; /* Never allow zero rtt or baseRTT */ | 87 | u32 vrtt; |
88 | |||
89 | /* Never allow zero rtt or baseRTT */ | ||
90 | vrtt = (ktime_to_ns(net_timedelta(last)) / NSEC_PER_USEC) + 1; | ||
88 | 91 | ||
89 | /* Filter to find propagation delay: */ | 92 | /* Filter to find propagation delay: */ |
90 | if (vrtt < vegas->baseRTT) | 93 | if (vrtt < vegas->baseRTT) |