Skip to content

Commit

Permalink
[TCP]: congestion control API pass RTT in microseconds
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Jul 31, 2007
1 parent 6a30235 commit 30cfd0b
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 29 deletions.
2 changes: 1 addition & 1 deletion include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ struct tcp_congestion_ops {
/* new value of cwnd after loss (optional) */
u32 (*undo_cwnd)(struct sock *sk);
/* 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) */
void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb);

Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_bic.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ static void bictcp_state(struct sock *sk, u8 new_state)
/* Track delayed acknowledgment ratio using sliding window
* 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);

Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_cubic.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ static void bictcp_state(struct sock *sk, u8 new_state)
/* Track delayed acknowledgment ratio using sliding window
* 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);

Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_htcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 tcp_sock *tp = tcp_sk(sk);
Expand Down
8 changes: 3 additions & 5 deletions net/ipv4/tcp_illinois.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,16 @@ static void tcp_illinois_init(struct sock *sk)
}

/* 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);
u32 rtt;

ca->acked = pkts_acked;

if (ktime_equal(last, net_invalid_timestamp()))
/* dup ack, no rtt sample */
if (rtt < 0)
return;

rtt = ktime_to_us(net_timedelta(last));

/* ignore bogus values, this prevents wraparound in alpha math */
if (rtt > RTT_MAX)
rtt = RTT_MAX;
Expand Down
21 changes: 16 additions & 5 deletions net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_packets_out(sk);

/* Is the ACK triggering packet unambiguous? */
if (acked & FLAG_RETRANS_DATA_ACKED)
last_ackt = net_invalid_timestamp();
if (ca_ops->pkts_acked) {
s32 rtt_us = -1;

/* Is the ACK triggering packet unambiguous? */
if (!(acked & FLAG_RETRANS_DATA_ACKED)) {
/* 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, last_ackt);
ca_ops->pkts_acked(sk, pkts_acked, rtt_us);
}
}

#if FASTRETRANS_DEBUG > 0
Expand Down
6 changes: 3 additions & 3 deletions net/ipv4/tcp_lp.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,13 @@ static void tcp_lp_rtt_sample(struct sock *sk, u32 rtt)
* newReno in increase case.
* 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 lp *lp = inet_csk_ca(sk);

if (!ktime_equal(last, net_invalid_timestamp()))
tcp_lp_rtt_sample(sk, ktime_to_us(net_timedelta(last)));
if (rtt_us > 0)
tcp_lp_rtt_sample(sk, rtt_us);

/* calc inference */
if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
Expand Down
6 changes: 3 additions & 3 deletions net/ipv4/tcp_vegas.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,16 @@ EXPORT_SYMBOL_GPL(tcp_vegas_init);
* o min-filter RTT samples from a much longer window (forever for now)
* 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);
u32 vrtt;

if (ktime_equal(last, net_invalid_timestamp()))
if (rtt_us < 0)
return;

/* Never allow zero rtt or baseRTT */
vrtt = ktime_to_us(net_timedelta(last)) + 1;
vrtt = rtt_us + 1;

/* Filter to find propagation delay: */
if (vrtt < vegas->baseRTT)
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/tcp_vegas.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct vegas {

extern void tcp_vegas_init(struct sock *sk);
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_get_info(struct sock *sk, u32 ext, struct sk_buff *skb);

Expand Down
6 changes: 3 additions & 3 deletions net/ipv4/tcp_veno.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ static void tcp_veno_init(struct sock *sk)
}

/* 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);
u32 vrtt;

if (ktime_equal(last, net_invalid_timestamp()))
if (rtt_us < 0)
return;

/* Never allow zero rtt or baseRTT */
vrtt = ktime_to_us(net_timedelta(last)) + 1;
vrtt = rtt_us + 1;

/* Filter to find propagation delay: */
if (vrtt < veno->basertt)
Expand Down
7 changes: 4 additions & 3 deletions net/ipv4/tcp_westwood.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,12 @@ static void westwood_filter(struct westwood *w, u32 delta)
* Called after processing group of packets.
* 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);
if (cnt > 0)
w->rtt = tcp_sk(sk)->srtt >> 3;

if (rtt > 0)
w->rtt = usecs_to_jiffies(rtt);
}

/*
Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/tcp_yeah.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ 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);
struct yeah *yeah = inet_csk_ca(sk);

if (icsk->icsk_ca_state == TCP_CA_Open)
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,
Expand Down

0 comments on commit 30cfd0b

Please sign in to comment.