tcp_xmit_retransmit_queue(sk);
 }
 
-static inline void tcp_ack_update_rtt(struct sock *sk, const int flag,
-                                     s32 seq_rtt)
+static inline bool tcp_ack_update_rtt(struct sock *sk, const int flag,
+                                     s32 seq_rtt, s32 sack_rtt)
 {
        const struct tcp_sock *tp = tcp_sk(sk);
 
        if (flag & FLAG_RETRANS_DATA_ACKED)
                seq_rtt = -1;
 
+       if (seq_rtt < 0)
+               seq_rtt = sack_rtt;
+
        /* RTTM Rule: A TSecr value received in a segment is used to
         * update the averaged RTT measurement only if the segment
         * acknowledges some new data, i.e., only if it advances the
                seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
 
        if (seq_rtt < 0)
-               return;
+               return false;
 
        tcp_rtt_estimator(sk, seq_rtt);
        tcp_set_rto(sk);
 
        /* RFC6298: only reset backoff on valid RTT measurement. */
        inet_csk(sk)->icsk_backoff = 0;
+       return true;
 }
 
 /* Compute time elapsed between (last) SYNACK and the ACK completing 3WHS. */
 
        if (tp->lsndtime && !tp->total_retrans)
                seq_rtt = tcp_time_stamp - tp->lsndtime;
-       tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, seq_rtt);
+       tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, seq_rtt, -1);
 }
 
 static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
  * arrived at the other end.
  */
 static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
-                              u32 prior_snd_una)
+                              u32 prior_snd_una, s32 sack_rtt)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
        if (skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
                flag |= FLAG_SACK_RENEGING;
 
+       if (tcp_ack_update_rtt(sk, flag, seq_rtt, sack_rtt) ||
+           (flag & FLAG_ACKED))
+               tcp_rearm_rto(sk);
+
        if (flag & FLAG_ACKED) {
                const struct tcp_congestion_ops *ca_ops
                        = inet_csk(sk)->icsk_ca_ops;
                        tcp_mtup_probe_success(sk);
                }
 
-               tcp_ack_update_rtt(sk, flag, seq_rtt);
-               tcp_rearm_rto(sk);
-
                if (tcp_is_reno(tp)) {
                        tcp_remove_reno_sacks(sk, pkts_acked);
                } else {
 
        /* See if we can take anything off of the retransmit queue. */
        acked = tp->packets_out;
-       flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);
+       flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, sack_rtt);
        acked -= tp->packets_out;
 
        if (tcp_ack_is_dubious(sk, flag)) {