Commit 30cfd0ba authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

[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: default avatarStephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6a302358
...@@ -660,7 +660,7 @@ struct tcp_congestion_ops { ...@@ -660,7 +660,7 @@ struct tcp_congestion_ops {
/* new value of cwnd after loss (optional) */ /* new value of cwnd after loss (optional) */
u32 (*undo_cwnd)(struct sock *sk); u32 (*undo_cwnd)(struct sock *sk);
/* hook for packet ack accounting (optional) */ /* hook for packet ack accounting (optional) */
void (*pkts_acked)(struct sock *sk, u32 num_acked, ktime_t last); void (*pkts_acked)(struct sock *sk, u32 num_acked, s32 rtt_us);
/* get info for inet_diag (optional) */ /* get info for inet_diag (optional) */
void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb); void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb);
......
...@@ -206,7 +206,7 @@ static void bictcp_state(struct sock *sk, u8 new_state) ...@@ -206,7 +206,7 @@ static void bictcp_state(struct sock *sk, u8 new_state)
/* Track delayed acknowledgment ratio using sliding window /* Track delayed acknowledgment ratio using sliding window
* ratio = (15*ratio + sample) / 16 * ratio = (15*ratio + sample) / 16
*/ */
static void bictcp_acked(struct sock *sk, u32 cnt, ktime_t last) static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt)
{ {
const struct inet_connection_sock *icsk = inet_csk(sk); const struct inet_connection_sock *icsk = inet_csk(sk);
......
...@@ -334,7 +334,7 @@ static void bictcp_state(struct sock *sk, u8 new_state) ...@@ -334,7 +334,7 @@ static void bictcp_state(struct sock *sk, u8 new_state)
/* Track delayed acknowledgment ratio using sliding window /* Track delayed acknowledgment ratio using sliding window
* ratio = (15*ratio + sample) / 16 * ratio = (15*ratio + sample) / 16
*/ */
static void bictcp_acked(struct sock *sk, u32 cnt, ktime_t last) static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
{ {
const struct inet_connection_sock *icsk = inet_csk(sk); const struct inet_connection_sock *icsk = inet_csk(sk);
......
...@@ -98,7 +98,7 @@ static inline void measure_rtt(struct sock *sk) ...@@ -98,7 +98,7 @@ static inline void measure_rtt(struct sock *sk)
} }
} }
static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked, ktime_t last) static void measure_achieved_throughput(struct sock *sk, u32 pkts_acked, s32 rtt)
{ {
const struct inet_connection_sock *icsk = inet_csk(sk); const struct inet_connection_sock *icsk = inet_csk(sk);
const struct tcp_sock *tp = tcp_sk(sk); const struct tcp_sock *tp = tcp_sk(sk);
......
...@@ -83,18 +83,16 @@ static void tcp_illinois_init(struct sock *sk) ...@@ -83,18 +83,16 @@ static void tcp_illinois_init(struct sock *sk)
} }
/* Measure RTT for each ack. */ /* Measure RTT for each ack. */
static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, ktime_t last) static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, s32 rtt)
{ {
struct illinois *ca = inet_csk_ca(sk); struct illinois *ca = inet_csk_ca(sk);
u32 rtt;
ca->acked = pkts_acked; ca->acked = pkts_acked;
if (ktime_equal(last, net_invalid_timestamp())) /* dup ack, no rtt sample */
if (rtt < 0)
return; return;
rtt = ktime_to_us(net_timedelta(last));
/* ignore bogus values, this prevents wraparound in alpha math */ /* ignore bogus values, this prevents wraparound in alpha math */
if (rtt > RTT_MAX) if (rtt > RTT_MAX)
rtt = RTT_MAX; rtt = RTT_MAX;
......
...@@ -2490,12 +2490,23 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) ...@@ -2490,12 +2490,23 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
tcp_ack_update_rtt(sk, acked, seq_rtt); tcp_ack_update_rtt(sk, acked, seq_rtt);
tcp_ack_packets_out(sk); tcp_ack_packets_out(sk);
if (ca_ops->pkts_acked) {
s32 rtt_us = -1;
/* Is the ACK triggering packet unambiguous? */ /* Is the ACK triggering packet unambiguous? */
if (acked & FLAG_RETRANS_DATA_ACKED) if (!(acked & FLAG_RETRANS_DATA_ACKED)) {
last_ackt = net_invalid_timestamp(); /* High resolution needed and available? */
if (ca_ops->flags & TCP_CONG_RTT_STAMP &&
!ktime_equal(last_ackt,
net_invalid_timestamp()))
rtt_us = ktime_us_delta(ktime_get_real(),
last_ackt);
else if (seq_rtt > 0)
rtt_us = jiffies_to_usecs(seq_rtt);
}
if (ca_ops->pkts_acked) ca_ops->pkts_acked(sk, pkts_acked, rtt_us);
ca_ops->pkts_acked(sk, pkts_acked, last_ackt); }
} }
#if FASTRETRANS_DEBUG > 0 #if FASTRETRANS_DEBUG > 0
......
...@@ -260,13 +260,13 @@ static void tcp_lp_rtt_sample(struct sock *sk, u32 rtt) ...@@ -260,13 +260,13 @@ static void tcp_lp_rtt_sample(struct sock *sk, u32 rtt)
* newReno in increase case. * newReno in increase case.
* We work it out by following the idea from TCP-LP's paper directly * We work it out by following the idea from TCP-LP's paper directly
*/ */
static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, ktime_t last) static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, s32 rtt_us)
{ {
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
struct lp *lp = inet_csk_ca(sk); struct lp *lp = inet_csk_ca(sk);
if (!ktime_equal(last, net_invalid_timestamp())) if (rtt_us > 0)
tcp_lp_rtt_sample(sk, ktime_to_us(net_timedelta(last))); tcp_lp_rtt_sample(sk, rtt_us);
/* calc inference */ /* calc inference */
if (tcp_time_stamp > tp->rx_opt.rcv_tsecr) if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
......
...@@ -112,16 +112,16 @@ EXPORT_SYMBOL_GPL(tcp_vegas_init); ...@@ -112,16 +112,16 @@ EXPORT_SYMBOL_GPL(tcp_vegas_init);
* o min-filter RTT samples from a much longer window (forever for now) * o min-filter RTT samples from a much longer window (forever for now)
* to find the propagation delay (baseRTT) * to find the propagation delay (baseRTT)
*/ */
void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us)
{ {
struct vegas *vegas = inet_csk_ca(sk); struct vegas *vegas = inet_csk_ca(sk);
u32 vrtt; u32 vrtt;
if (ktime_equal(last, net_invalid_timestamp())) if (rtt_us < 0)
return; return;
/* Never allow zero rtt or baseRTT */ /* Never allow zero rtt or baseRTT */
vrtt = ktime_to_us(net_timedelta(last)) + 1; vrtt = rtt_us + 1;
/* Filter to find propagation delay: */ /* Filter to find propagation delay: */
if (vrtt < vegas->baseRTT) if (vrtt < vegas->baseRTT)
......
...@@ -17,7 +17,7 @@ struct vegas { ...@@ -17,7 +17,7 @@ struct vegas {
extern void tcp_vegas_init(struct sock *sk); extern void tcp_vegas_init(struct sock *sk);
extern void tcp_vegas_state(struct sock *sk, u8 ca_state); extern void tcp_vegas_state(struct sock *sk, u8 ca_state);
extern void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last); extern void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us);
extern void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event); extern void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event);
extern void tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb); extern void tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb);
......
...@@ -69,16 +69,16 @@ static void tcp_veno_init(struct sock *sk) ...@@ -69,16 +69,16 @@ static void tcp_veno_init(struct sock *sk)
} }
/* Do rtt sampling needed for Veno. */ /* Do rtt sampling needed for Veno. */
static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us)
{ {
struct veno *veno = inet_csk_ca(sk); struct veno *veno = inet_csk_ca(sk);
u32 vrtt; u32 vrtt;
if (ktime_equal(last, net_invalid_timestamp())) if (rtt_us < 0)
return; return;
/* Never allow zero rtt or baseRTT */ /* Never allow zero rtt or baseRTT */
vrtt = ktime_to_us(net_timedelta(last)) + 1; vrtt = rtt_us + 1;
/* Filter to find propagation delay: */ /* Filter to find propagation delay: */
if (vrtt < veno->basertt) if (vrtt < veno->basertt)
......
...@@ -100,11 +100,12 @@ static void westwood_filter(struct westwood *w, u32 delta) ...@@ -100,11 +100,12 @@ static void westwood_filter(struct westwood *w, u32 delta)
* Called after processing group of packets. * Called after processing group of packets.
* but all westwood needs is the last sample of srtt. * but all westwood needs is the last sample of srtt.
*/ */
static void tcp_westwood_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) static void tcp_westwood_pkts_acked(struct sock *sk, u32 cnt, s32 rtt)
{ {
struct westwood *w = inet_csk_ca(sk); struct westwood *w = inet_csk_ca(sk);
if (cnt > 0)
w->rtt = tcp_sk(sk)->srtt >> 3; if (rtt > 0)
w->rtt = usecs_to_jiffies(rtt);
} }
/* /*
......
...@@ -58,7 +58,7 @@ static void tcp_yeah_init(struct sock *sk) ...@@ -58,7 +58,7 @@ static void tcp_yeah_init(struct sock *sk)
} }
static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, ktime_t last) static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, s32 rtt_us)
{ {
const struct inet_connection_sock *icsk = inet_csk(sk); const struct inet_connection_sock *icsk = inet_csk(sk);
struct yeah *yeah = inet_csk_ca(sk); 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,7 +66,7 @@ static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, ktime_t last)
if (icsk->icsk_ca_state == TCP_CA_Open) if (icsk->icsk_ca_state == TCP_CA_Open)
yeah->pkts_acked = pkts_acked; yeah->pkts_acked = pkts_acked;
tcp_vegas_pkts_acked(sk, pkts_acked, last); tcp_vegas_pkts_acked(sk, pkts_acked, rtt_us);
} }
static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment