aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/tcp.h2
-rw-r--r--net/ipv4/tcp_input.c26
2 files changed, 12 insertions, 16 deletions
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index fa5258f322e7..e567f0dbf282 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -276,7 +276,7 @@ struct tcp_sock {
276 u32 retrans_stamp; /* Timestamp of the last retransmit, 276 u32 retrans_stamp; /* Timestamp of the last retransmit,
277 * also used in SYN-SENT to remember stamp of 277 * also used in SYN-SENT to remember stamp of
278 * the first SYN. */ 278 * the first SYN. */
279 u32 undo_marker; /* tracking retrans started here. */ 279 u32 undo_marker; /* snd_una upon a new recovery episode. */
280 int undo_retrans; /* number of undoable retransmissions. */ 280 int undo_retrans; /* number of undoable retransmissions. */
281 u32 total_retrans; /* Total retransmits for entire connection */ 281 u32 total_retrans; /* Total retransmits for entire connection */
282 282
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a906e0200ff2..aba4926ca095 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1888,21 +1888,21 @@ static inline void tcp_reset_reno_sack(struct tcp_sock *tp)
1888 tp->sacked_out = 0; 1888 tp->sacked_out = 0;
1889} 1889}
1890 1890
1891static void tcp_clear_retrans_partial(struct tcp_sock *tp) 1891void tcp_clear_retrans(struct tcp_sock *tp)
1892{ 1892{
1893 tp->retrans_out = 0; 1893 tp->retrans_out = 0;
1894 tp->lost_out = 0; 1894 tp->lost_out = 0;
1895
1896 tp->undo_marker = 0; 1895 tp->undo_marker = 0;
1897 tp->undo_retrans = -1; 1896 tp->undo_retrans = -1;
1897 tp->fackets_out = 0;
1898 tp->sacked_out = 0;
1898} 1899}
1899 1900
1900void tcp_clear_retrans(struct tcp_sock *tp) 1901static inline void tcp_init_undo(struct tcp_sock *tp)
1901{ 1902{
1902 tcp_clear_retrans_partial(tp); 1903 tp->undo_marker = tp->snd_una;
1903 1904 /* Retransmission still in flight may cause DSACKs later. */
1904 tp->fackets_out = 0; 1905 tp->undo_retrans = tp->retrans_out ? : -1;
1905 tp->sacked_out = 0;
1906} 1906}
1907 1907
1908/* Enter Loss state. If we detect SACK reneging, forget all SACK information 1908/* Enter Loss state. If we detect SACK reneging, forget all SACK information
@@ -1925,18 +1925,18 @@ void tcp_enter_loss(struct sock *sk)
1925 tp->prior_ssthresh = tcp_current_ssthresh(sk); 1925 tp->prior_ssthresh = tcp_current_ssthresh(sk);
1926 tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk); 1926 tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk);
1927 tcp_ca_event(sk, CA_EVENT_LOSS); 1927 tcp_ca_event(sk, CA_EVENT_LOSS);
1928 tcp_init_undo(tp);
1928 } 1929 }
1929 tp->snd_cwnd = 1; 1930 tp->snd_cwnd = 1;
1930 tp->snd_cwnd_cnt = 0; 1931 tp->snd_cwnd_cnt = 0;
1931 tp->snd_cwnd_stamp = tcp_time_stamp; 1932 tp->snd_cwnd_stamp = tcp_time_stamp;
1932 1933
1933 tcp_clear_retrans_partial(tp); 1934 tp->retrans_out = 0;
1935 tp->lost_out = 0;
1934 1936
1935 if (tcp_is_reno(tp)) 1937 if (tcp_is_reno(tp))
1936 tcp_reset_reno_sack(tp); 1938 tcp_reset_reno_sack(tp);
1937 1939
1938 tp->undo_marker = tp->snd_una;
1939
1940 skb = tcp_write_queue_head(sk); 1940 skb = tcp_write_queue_head(sk);
1941 is_reneg = skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED); 1941 is_reneg = skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED);
1942 if (is_reneg) { 1942 if (is_reneg) {
@@ -1950,9 +1950,6 @@ void tcp_enter_loss(struct sock *sk)
1950 if (skb == tcp_send_head(sk)) 1950 if (skb == tcp_send_head(sk))
1951 break; 1951 break;
1952 1952
1953 if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)
1954 tp->undo_marker = 0;
1955
1956 TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED; 1953 TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED;
1957 if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || is_reneg) { 1954 if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || is_reneg) {
1958 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED; 1955 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED;
@@ -2671,8 +2668,7 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack)
2671 NET_INC_STATS_BH(sock_net(sk), mib_idx); 2668 NET_INC_STATS_BH(sock_net(sk), mib_idx);
2672 2669
2673 tp->prior_ssthresh = 0; 2670 tp->prior_ssthresh = 0;
2674 tp->undo_marker = tp->snd_una; 2671 tcp_init_undo(tp);
2675 tp->undo_retrans = tp->retrans_out ? : -1;
2676 2672
2677 if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { 2673 if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
2678 if (!ece_ack) 2674 if (!ece_ack)