aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-07-26 02:49:34 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-31 05:27:57 -0400
commit30cfd0baf0a0c4329fff1ef4b622919297969ec8 (patch)
tree945a72f636ced1b443d894495704237e4cb7816d
parent6a302358d87fedaf7bda12b8e909265ebf1ce674 (diff)
[TCP]: congestion control API pass RTT in microseconds
This patch changes the API for the callback that is done after an ACK is received. It solves a couple of issues: * Some congestion controls want higher resolution value of RTT (controlled by TCP_CONG_RTT_SAMPLE flag). These don't really want a ktime, but all compute a RTT in microseconds. * Other congestion control could use RTT at jiffies resolution. To keep API consistent the units should be the same for both cases, just the resolution should change. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/tcp.h2
-rw-r--r--net/ipv4/tcp_bic.c2
-rw-r--r--net/ipv4/tcp_cubic.c2
-rw-r--r--net/ipv4/tcp_htcp.c2
-rw-r--r--net/ipv4/tcp_illinois.c8
-rw-r--r--net/ipv4/tcp_input.c21
-rw-r--r--net/ipv4/tcp_lp.c6
-rw-r--r--net/ipv4/tcp_vegas.c6
-rw-r--r--net/ipv4/tcp_vegas.h2
-rw-r--r--net/ipv4/tcp_veno.c6
-rw-r--r--net/ipv4/tcp_westwood.c7
-rw-r--r--net/ipv4/tcp_yeah.c4
12 files changed, 39 insertions, 29 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 8b404b1ef7c8..c209361ab74a 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -660,7 +660,7 @@ struct tcp_congestion_ops {
660 /* new value of cwnd after loss (optional) */ 660 /* new value of cwnd after loss (optional) */
661 u32 (*undo_cwnd)(struct sock *sk); 661 u32 (*undo_cwnd)(struct sock *sk);
662 /* hook for packet ack accounting (optional) */ 662 /* hook for packet ack accounting (optional) */
663 void (*pkts_acked)(struct sock *sk, u32 num_acked, ktime_t last); 663 void (*pkts_acked)(struct sock *sk, u32 num_acked, s32 rtt_us);
664 /* get info for inet_diag (optional) */ 664 /* get info for inet_diag (optional) */
665 void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb); 665 void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb);
666 666
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index 519de091a94d..4586211e3757 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 */
209static void bictcp_acked(struct sock *sk, u32 cnt, ktime_t last) 209static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt)
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_cubic.c b/net/ipv4/tcp_cubic.c
index d17da30d82d6..0c44bb67a671 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 */
337static void bictcp_acked(struct sock *sk, u32 cnt, ktime_t last) 337static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
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 08a02e6045c9..fa61663ace3b 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
101static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked, ktime_t last) 101static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked, s32 rtt)
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 cc5de6f69d46..64f1cbaf96e8 100644
--- a/net/ipv4/tcp_illinois.c
+++ b/net/ipv4/tcp_illinois.c
@@ -83,18 +83,16 @@ static void tcp_illinois_init(struct sock *sk)
83} 83}
84 84
85/* Measure RTT for each ack. */ 85/* Measure RTT for each ack. */
86static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, ktime_t last) 86static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, s32 rtt)
87{ 87{
88 struct illinois *ca = inet_csk_ca(sk); 88 struct illinois *ca = inet_csk_ca(sk);
89 u32 rtt;
90 89
91 ca->acked = pkts_acked; 90 ca->acked = pkts_acked;
92 91
93 if (ktime_equal(last, net_invalid_timestamp())) 92 /* dup ack, no rtt sample */
93 if (rtt < 0)
94 return; 94 return;
95 95
96 rtt = ktime_to_us(net_timedelta(last));
97
98 /* ignore bogus values, this prevents wraparound in alpha math */ 96 /* ignore bogus values, this prevents wraparound in alpha math */
99 if (rtt > RTT_MAX) 97 if (rtt > RTT_MAX)
100 rtt = RTT_MAX; 98 rtt = RTT_MAX;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index fec8a7a4dbaf..4b255fe999d9 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2490,12 +2490,23 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2490 tcp_ack_update_rtt(sk, acked, seq_rtt); 2490 tcp_ack_update_rtt(sk, acked, seq_rtt);
2491 tcp_ack_packets_out(sk); 2491 tcp_ack_packets_out(sk);
2492 2492
2493 /* Is the ACK triggering packet unambiguous? */ 2493 if (ca_ops->pkts_acked) {
2494 if (acked & FLAG_RETRANS_DATA_ACKED) 2494 s32 rtt_us = -1;
2495 last_ackt = net_invalid_timestamp(); 2495
2496 /* Is the ACK triggering packet unambiguous? */
2497 if (!(acked & FLAG_RETRANS_DATA_ACKED)) {
2498 /* High resolution needed and available? */
2499 if (ca_ops->flags & TCP_CONG_RTT_STAMP &&
2500 !ktime_equal(last_ackt,
2501 net_invalid_timestamp()))
2502 rtt_us = ktime_us_delta(ktime_get_real(),
2503 last_ackt);
2504 else if (seq_rtt > 0)
2505 rtt_us = jiffies_to_usecs(seq_rtt);
2506 }
2496 2507
2497 if (ca_ops->pkts_acked) 2508 ca_ops->pkts_acked(sk, pkts_acked, rtt_us);
2498 ca_ops->pkts_acked(sk, pkts_acked, last_ackt); 2509 }
2499 } 2510 }
2500 2511
2501#if FASTRETRANS_DEBUG > 0 2512#if FASTRETRANS_DEBUG > 0
diff --git a/net/ipv4/tcp_lp.c b/net/ipv4/tcp_lp.c
index 80e140e3ec2d..e7f5ef92cbd8 100644
--- a/net/ipv4/tcp_lp.c
+++ b/net/ipv4/tcp_lp.c
@@ -260,13 +260,13 @@ static void tcp_lp_rtt_sample(struct sock *sk, u32 rtt)
260 * newReno in increase case. 260 * newReno in increase case.
261 * We work it out by following the idea from TCP-LP's paper directly 261 * We work it out by following the idea from TCP-LP's paper directly
262 */ 262 */
263static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, ktime_t last) 263static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, s32 rtt_us)
264{ 264{
265 struct tcp_sock *tp = tcp_sk(sk); 265 struct tcp_sock *tp = tcp_sk(sk);
266 struct lp *lp = inet_csk_ca(sk); 266 struct lp *lp = inet_csk_ca(sk);
267 267
268 if (!ktime_equal(last, net_invalid_timestamp())) 268 if (rtt_us > 0)
269 tcp_lp_rtt_sample(sk, ktime_to_us(net_timedelta(last))); 269 tcp_lp_rtt_sample(sk, rtt_us);
270 270
271 /* calc inference */ 271 /* calc inference */
272 if (tcp_time_stamp > tp->rx_opt.rcv_tsecr) 272 if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index 914e0307f7af..b49dedcda52d 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -112,16 +112,16 @@ EXPORT_SYMBOL_GPL(tcp_vegas_init);
112 * o min-filter RTT samples from a much longer window (forever for now) 112 * o min-filter RTT samples from a much longer window (forever for now)
113 * to find the propagation delay (baseRTT) 113 * to find the propagation delay (baseRTT)
114 */ 114 */
115void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) 115void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us)
116{ 116{
117 struct vegas *vegas = inet_csk_ca(sk); 117 struct vegas *vegas = inet_csk_ca(sk);
118 u32 vrtt; 118 u32 vrtt;
119 119
120 if (ktime_equal(last, net_invalid_timestamp())) 120 if (rtt_us < 0)
121 return; 121 return;
122 122
123 /* Never allow zero rtt or baseRTT */ 123 /* Never allow zero rtt or baseRTT */
124 vrtt = ktime_to_us(net_timedelta(last)) + 1; 124 vrtt = rtt_us + 1;
125 125
126 /* Filter to find propagation delay: */ 126 /* Filter to find propagation delay: */
127 if (vrtt < vegas->baseRTT) 127 if (vrtt < vegas->baseRTT)
diff --git a/net/ipv4/tcp_vegas.h b/net/ipv4/tcp_vegas.h
index 502fa8183634..6c0eea2f8249 100644
--- a/net/ipv4/tcp_vegas.h
+++ b/net/ipv4/tcp_vegas.h
@@ -17,7 +17,7 @@ struct vegas {
17 17
18extern void tcp_vegas_init(struct sock *sk); 18extern void tcp_vegas_init(struct sock *sk);
19extern void tcp_vegas_state(struct sock *sk, u8 ca_state); 19extern void tcp_vegas_state(struct sock *sk, u8 ca_state);
20extern void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last); 20extern void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us);
21extern void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event); 21extern void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event);
22extern void tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb); 22extern void tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb);
23 23
diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c
index 7a55ddf86032..8fb2aee0b1a4 100644
--- a/net/ipv4/tcp_veno.c
+++ b/net/ipv4/tcp_veno.c
@@ -69,16 +69,16 @@ 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. */
72static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) 72static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us)
73{ 73{
74 struct veno *veno = inet_csk_ca(sk); 74 struct veno *veno = inet_csk_ca(sk);
75 u32 vrtt; 75 u32 vrtt;
76 76
77 if (ktime_equal(last, net_invalid_timestamp())) 77 if (rtt_us < 0)
78 return; 78 return;
79 79
80 /* Never allow zero rtt or baseRTT */ 80 /* Never allow zero rtt or baseRTT */
81 vrtt = ktime_to_us(net_timedelta(last)) + 1; 81 vrtt = rtt_us + 1;
82 82
83 /* Filter to find propagation delay: */ 83 /* Filter to find propagation delay: */
84 if (vrtt < veno->basertt) 84 if (vrtt < veno->basertt)
diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c
index e61e09dd513e..20151d6a6241 100644
--- a/net/ipv4/tcp_westwood.c
+++ b/net/ipv4/tcp_westwood.c
@@ -100,11 +100,12 @@ 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 */
103static void tcp_westwood_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) 103static void tcp_westwood_pkts_acked(struct sock *sk, u32 cnt, s32 rtt)
104{ 104{
105 struct westwood *w = inet_csk_ca(sk); 105 struct westwood *w = inet_csk_ca(sk);
106 if (cnt > 0) 106
107 w->rtt = tcp_sk(sk)->srtt >> 3; 107 if (rtt > 0)
108 w->rtt = usecs_to_jiffies(rtt);
108} 109}
109 110
110/* 111/*
diff --git a/net/ipv4/tcp_yeah.c b/net/ipv4/tcp_yeah.c
index c04b7c6ec702..c107fba7430e 100644
--- a/net/ipv4/tcp_yeah.c
+++ b/net/ipv4/tcp_yeah.c
@@ -58,7 +58,7 @@ static void tcp_yeah_init(struct sock *sk)
58} 58}
59 59
60 60
61static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, ktime_t last) 61static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, s32 rtt_us)
62{ 62{
63 const struct inet_connection_sock *icsk = inet_csk(sk); 63 const struct inet_connection_sock *icsk = inet_csk(sk);
64 struct yeah *yeah = inet_csk_ca(sk); 64 struct yeah *yeah = inet_csk_ca(sk);
@@ -66,7 +66,7 @@ static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, ktime_t last)
66 if (icsk->icsk_ca_state == TCP_CA_Open) 66 if (icsk->icsk_ca_state == TCP_CA_Open)
67 yeah->pkts_acked = pkts_acked; 67 yeah->pkts_acked = pkts_acked;
68 68
69 tcp_vegas_pkts_acked(sk, pkts_acked, last); 69 tcp_vegas_pkts_acked(sk, pkts_acked, rtt_us);
70} 70}
71 71
72static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, 72static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack,