tcp: always set retrans_stamp on recovery
[linux-2.6-microblaze.git] / net / ipv4 / tcp_output.c
index 730bc44..d2d494c 100644 (file)
@@ -980,7 +980,6 @@ static void tcp_update_skb_after_send(struct sock *sk, struct sk_buff *skb,
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
-       skb->skb_mstamp_ns = tp->tcp_wstamp_ns;
        if (sk->sk_pacing_status != SK_PACING_NONE) {
                unsigned long rate = sk->sk_pacing_rate;
 
@@ -1028,7 +1027,9 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,
 
        BUG_ON(!skb || !tcp_skb_pcount(skb));
        tp = tcp_sk(sk);
-
+       prior_wstamp = tp->tcp_wstamp_ns;
+       tp->tcp_wstamp_ns = max(tp->tcp_wstamp_ns, tp->tcp_clock_cache);
+       skb->skb_mstamp_ns = tp->tcp_wstamp_ns;
        if (clone_it) {
                TCP_SKB_CB(skb)->tx.in_flight = TCP_SKB_CB(skb)->end_seq
                        - tp->snd_una;
@@ -1045,11 +1046,6 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,
                        return -ENOBUFS;
        }
 
-       prior_wstamp = tp->tcp_wstamp_ns;
-       tp->tcp_wstamp_ns = max(tp->tcp_wstamp_ns, tp->tcp_clock_cache);
-
-       skb->skb_mstamp_ns = tp->tcp_wstamp_ns;
-
        inet = inet_sk(sk);
        tcb = TCP_SKB_CB(skb);
        memset(&opts, 0, sizeof(opts));
@@ -2937,12 +2933,16 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
                err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
        }
 
+       /* To avoid taking spuriously low RTT samples based on a timestamp
+        * for a transmit that never happened, always mark EVER_RETRANS
+        */
+       TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS;
+
        if (BPF_SOCK_OPS_TEST_FLAG(tp, BPF_SOCK_OPS_RETRANS_CB_FLAG))
                tcp_call_bpf_3arg(sk, BPF_SOCK_OPS_RETRANS_CB,
                                  TCP_SKB_CB(skb)->seq, segs, err);
 
        if (likely(!err)) {
-               TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS;
                trace_tcp_retransmit_skb(sk, skb);
        } else if (err != -EBUSY) {
                NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL, segs);
@@ -2963,13 +2963,12 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
 #endif
                TCP_SKB_CB(skb)->sacked |= TCPCB_RETRANS;
                tp->retrans_out += tcp_skb_pcount(skb);
-
-               /* Save stamp of the first retransmit. */
-               if (!tp->retrans_stamp)
-                       tp->retrans_stamp = tcp_skb_timestamp(skb);
-
        }
 
+       /* Save stamp of the first (attempted) retransmit. */
+       if (!tp->retrans_stamp)
+               tp->retrans_stamp = tcp_skb_timestamp(skb);
+
        if (tp->undo_retrans < 0)
                tp->undo_retrans = 0;
        tp->undo_retrans += tcp_skb_pcount(skb);