diff --git a/include/linux/ktime.h b/include/linux/ktime.h index c762954bda148fa18ab13f6d1f71aab26d2e3441..2b139f66027f3de7ae5f1a60df00ddf39c8cb147 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -261,6 +261,18 @@ static inline s64 ktime_to_ns(const ktime_t kt) #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) { struct timeval tv = ktime_to_timeval(kt); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index e7367c74e1bbedbca7c81ad69215d0e751deb9bb..6f0b2f7d00108835253403dc5f74039b49e3d002 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1579,6 +1579,10 @@ static inline ktime_t net_timedelta(ktime_t 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(struct sk_buff *skb); diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c index 4adc47c55351a49d09d172b1cb5a3baa194207bc..b2b2256d3b8450c944bc8d3a8869a76aaf2ceb69 100644 --- a/net/ipv4/tcp_illinois.c +++ b/net/ipv4/tcp_illinois.c @@ -90,6 +90,9 @@ static void tcp_illinois_acked(struct sock *sk, u32 pkts_acked, ktime_t last) ca->acked = pkts_acked; + if (ktime_equal(last, net_invalid_timestamp())) + return; + rtt = ktime_to_us(net_timedelta(last)); /* ignore bogus values, this prevents wraparound in alpha math */ diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index d6d0f9b6cdc6f3eda97ea76b6c69610fba902b6a..aaf6f66677f992fc09dcf19f135eb483252efcf3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2409,7 +2409,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) int acked = 0; int prior_packets = tp->packets_out; __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)) && skb != tcp_send_head(sk)) { @@ -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_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) ca_ops->pkts_acked(sk, pkts_acked, last_ackt); } diff --git a/net/ipv4/tcp_lp.c b/net/ipv4/tcp_lp.c index 43294ad9f63ef839cd26f693ccf1a4eb8b4173ee..e49836ce012e768a4586432f7b62be9a0b6e5140 100644 --- a/net/ipv4/tcp_lp.c +++ b/net/ipv4/tcp_lp.c @@ -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 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 */ if (tcp_time_stamp > tp->rx_opt.rcv_tsecr) diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c index 73e19cf7df2176e6189c45569939bf42e51f0363..e218a51ceced186b9c37acab906009dfbfe94233 100644 --- a/net/ipv4/tcp_vegas.c +++ b/net/ipv4/tcp_vegas.c @@ -117,6 +117,9 @@ void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, ktime_t last) struct vegas *vegas = inet_csk_ca(sk); u32 vrtt; + if (ktime_equal(last, net_invalid_timestamp())) + return; + /* Never allow zero rtt or baseRTT */ vrtt = ktime_to_us(net_timedelta(last)) + 1; diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c index 9edb340f2f95c6e003f5ff09f135425423881134..ec854cc5fad50fd90899818086310cd51b61cbdc 100644 --- a/net/ipv4/tcp_veno.c +++ b/net/ipv4/tcp_veno.c @@ -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); u32 vrtt; + if (ktime_equal(last, net_invalid_timestamp())) + return; + /* Never allow zero rtt or baseRTT */ vrtt = ktime_to_us(net_timedelta(last)) + 1;