min_t(u32, val, DCCPF_ACK_RATIO_MAX));
 }
 
+static void ccid2_check_l_ack_ratio(struct sock *sk)
+{
+       struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
+
+       /*
+        * After a loss, idle period, application limited period, or RTO we
+        * need to check that the ack ratio is still less than the congestion
+        * window. Otherwise, we will send an entire congestion window of
+        * packets and got no response because we haven't sent ack ratio
+        * packets yet.
+        * If the ack ratio does need to be reduced, we reduce it to half of
+        * the congestion window (or 1 if that's zero) instead of to the
+        * congestion window. This prevents problems if one ack is lost.
+        */
+       if (dccp_feat_nn_get(sk, DCCPF_ACK_RATIO) > hc->tx_cwnd)
+               ccid2_change_l_ack_ratio(sk, hc->tx_cwnd/2 ? : 1U);
+}
+
 static void ccid2_change_l_seq_window(struct sock *sk, u64 val)
 {
        dccp_feat_signal_nn_change(sk, DCCPF_SEQUENCE_WINDOW,
        }
        hc->tx_cwnd_used  = 0;
        hc->tx_cwnd_stamp = now;
+
+       ccid2_check_l_ack_ratio(sk);
 }
 
 /* This borrows the code of tcp_cwnd_restart() */
 
        hc->tx_cwnd_stamp = now;
        hc->tx_cwnd_used  = 0;
+
+       ccid2_check_l_ack_ratio(sk);
 }
 
 static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len)
        hc->tx_cwnd      = hc->tx_cwnd / 2 ? : 1U;
        hc->tx_ssthresh  = max(hc->tx_cwnd, 2U);
 
-       /* Avoid spurious timeouts resulting from Ack Ratio > cwnd */
-       if (dccp_sk(sk)->dccps_l_ack_ratio > hc->tx_cwnd)
-               ccid2_change_l_ack_ratio(sk, hc->tx_cwnd);
+       ccid2_check_l_ack_ratio(sk);
 }
 
 static int ccid2_hc_tx_parse_options(struct sock *sk, u8 packet_type,