Commit b9ce204f authored by Ilpo Järvinen's avatar Ilpo Järvinen Committed by David S. Miller

[TCP]: Congestion control API RTT sampling fix

Commit 164891aa broke RTT
sampling of congestion control modules. Inaccurate timestamps
could be fed to them without providing any way for them to
identify such cases. Previously RTT sampler was called only if
FLAG_RETRANS_DATA_ACKED was not set filtering inaccurate
timestamps nicely. In addition, the new behavior could give an
invalid timestamp (zero) to RTT sampler if only skbs with
TCPCB_RETRANS were ACKed. This solves both problems.
Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 22b1a920
...@@ -261,6 +261,18 @@ static inline s64 ktime_to_ns(const ktime_t kt) ...@@ -261,6 +261,18 @@ static inline s64 ktime_to_ns(const ktime_t kt)
#endif #endif
/**
* ktime_equal - Compares two ktime_t variables to see if they are equal
* @cmp1: comparable1
* @cmp2: comparable2
*
* Compare two ktime_t variables, returns 1 if equal
*/
static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2)
{
return cmp1.tv64 == cmp2.tv64;
}
static inline s64 ktime_to_us(const ktime_t kt) static inline s64 ktime_to_us(const ktime_t kt)
{ {
struct timeval tv = ktime_to_timeval(kt); struct timeval tv = ktime_to_timeval(kt);
......
...@@ -1579,6 +1579,10 @@ static inline ktime_t net_timedelta(ktime_t t) ...@@ -1579,6 +1579,10 @@ static inline ktime_t net_timedelta(ktime_t t)
return ktime_sub(ktime_get_real(), t); return ktime_sub(ktime_get_real(), t);
} }
static inline ktime_t net_invalid_timestamp(void)
{
return ktime_set(0, 0);
}
extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len); extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len);
extern __sum16 __skb_checksum_complete(struct sk_buff *skb); extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
......
...@@ -90,6 +90,9 @@ static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, ktime_t last) ...@@ -90,6 +90,9 @@ static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, ktime_t last)
ca->acked = pkts_acked; ca->acked = pkts_acked;
if (ktime_equal(last, net_invalid_timestamp()))
return;
rtt = ktime_to_us(net_timedelta(last)); 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 */
......
...@@ -2409,7 +2409,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) ...@@ -2409,7 +2409,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
int acked = 0; int acked = 0;
int prior_packets = tp->packets_out; int prior_packets = tp->packets_out;
__s32 seq_rtt = -1; __s32 seq_rtt = -1;
ktime_t last_ackt = ktime_set(0,0); ktime_t last_ackt = net_invalid_timestamp();
while ((skb = tcp_write_queue_head(sk)) && while ((skb = tcp_write_queue_head(sk)) &&
skb != tcp_send_head(sk)) { skb != tcp_send_head(sk)) {
...@@ -2487,6 +2487,10 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) ...@@ -2487,6 +2487,10 @@ 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);
/* Is the ACK triggering packet unambiguous? */
if (acked & FLAG_RETRANS_DATA_ACKED)
last_ackt = net_invalid_timestamp();
if (ca_ops->pkts_acked) if (ca_ops->pkts_acked)
ca_ops->pkts_acked(sk, pkts_acked, last_ackt); ca_ops->pkts_acked(sk, pkts_acked, last_ackt);
} }
......
...@@ -266,7 +266,8 @@ static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, ktime_t last) ...@@ -266,7 +266,8 @@ static void tcp_lp_pkts_acked(struct sock *sk, u32 num_acked, ktime_t last)
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);
tcp_lp_rtt_sample(sk, ktime_to_us(net_timedelta(last))); if (!ktime_equal(last, net_invalid_timestamp()))
tcp_lp_rtt_sample(sk, ktime_to_us(net_timedelta(last)));
/* calc inference */ /* calc inference */
if (tcp_time_stamp > tp->rx_opt.rcv_tsecr) if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
......
...@@ -117,6 +117,9 @@ void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) ...@@ -117,6 +117,9 @@ void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last)
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()))
return;
/* Never allow zero rtt or baseRTT */ /* Never allow zero rtt or baseRTT */
vrtt = ktime_to_us(net_timedelta(last)) + 1; vrtt = ktime_to_us(net_timedelta(last)) + 1;
......
...@@ -74,6 +74,9 @@ static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) ...@@ -74,6 +74,9 @@ static void tcp_veno_pkts_acked(struct sock *sk, u32 cnt, ktime_t last)
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()))
return;
/* Never allow zero rtt or baseRTT */ /* Never allow zero rtt or baseRTT */
vrtt = ktime_to_us(net_timedelta(last)) + 1; vrtt = ktime_to_us(net_timedelta(last)) + 1;
......
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