aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 734cfc8ff76e..9550cc42de2d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -579,6 +579,7 @@ void tcp_rcv_space_adjust(struct sock *sk)
579 int time; 579 int time;
580 int copied; 580 int copied;
581 581
582 tcp_mstamp_refresh(tp);
582 time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time); 583 time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time);
583 if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) 584 if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0)
584 return; 585 return;
@@ -1941,6 +1942,8 @@ void tcp_enter_loss(struct sock *sk)
1941 if (is_reneg) { 1942 if (is_reneg) {
1942 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSACKRENEGING); 1943 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSACKRENEGING);
1943 tp->sacked_out = 0; 1944 tp->sacked_out = 0;
1945 /* Mark SACK reneging until we recover from this loss event. */
1946 tp->is_sack_reneg = 1;
1944 } 1947 }
1945 tcp_clear_all_retrans_hints(tp); 1948 tcp_clear_all_retrans_hints(tp);
1946 1949
@@ -2326,6 +2329,7 @@ static void tcp_undo_cwnd_reduction(struct sock *sk, bool unmark_loss)
2326 } 2329 }
2327 tp->snd_cwnd_stamp = tcp_jiffies32; 2330 tp->snd_cwnd_stamp = tcp_jiffies32;
2328 tp->undo_marker = 0; 2331 tp->undo_marker = 0;
2332 tp->rack.advanced = 1; /* Force RACK to re-exam losses */
2329} 2333}
2330 2334
2331static inline bool tcp_may_undo(const struct tcp_sock *tp) 2335static inline bool tcp_may_undo(const struct tcp_sock *tp)
@@ -2364,6 +2368,7 @@ static bool tcp_try_undo_recovery(struct sock *sk)
2364 return true; 2368 return true;
2365 } 2369 }
2366 tcp_set_ca_state(sk, TCP_CA_Open); 2370 tcp_set_ca_state(sk, TCP_CA_Open);
2371 tp->is_sack_reneg = 0;
2367 return false; 2372 return false;
2368} 2373}
2369 2374
@@ -2397,8 +2402,10 @@ static bool tcp_try_undo_loss(struct sock *sk, bool frto_undo)
2397 NET_INC_STATS(sock_net(sk), 2402 NET_INC_STATS(sock_net(sk),
2398 LINUX_MIB_TCPSPURIOUSRTOS); 2403 LINUX_MIB_TCPSPURIOUSRTOS);
2399 inet_csk(sk)->icsk_retransmits = 0; 2404 inet_csk(sk)->icsk_retransmits = 0;
2400 if (frto_undo || tcp_is_sack(tp)) 2405 if (frto_undo || tcp_is_sack(tp)) {
2401 tcp_set_ca_state(sk, TCP_CA_Open); 2406 tcp_set_ca_state(sk, TCP_CA_Open);
2407 tp->is_sack_reneg = 0;
2408 }
2402 return true; 2409 return true;
2403 } 2410 }
2404 return false; 2411 return false;
@@ -3495,6 +3502,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3495 struct tcp_sacktag_state sack_state; 3502 struct tcp_sacktag_state sack_state;
3496 struct rate_sample rs = { .prior_delivered = 0 }; 3503 struct rate_sample rs = { .prior_delivered = 0 };
3497 u32 prior_snd_una = tp->snd_una; 3504 u32 prior_snd_una = tp->snd_una;
3505 bool is_sack_reneg = tp->is_sack_reneg;
3498 u32 ack_seq = TCP_SKB_CB(skb)->seq; 3506 u32 ack_seq = TCP_SKB_CB(skb)->seq;
3499 u32 ack = TCP_SKB_CB(skb)->ack_seq; 3507 u32 ack = TCP_SKB_CB(skb)->ack_seq;
3500 bool is_dupack = false; 3508 bool is_dupack = false;
@@ -3611,7 +3619,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3611 3619
3612 delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */ 3620 delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */
3613 lost = tp->lost - lost; /* freshly marked lost */ 3621 lost = tp->lost - lost; /* freshly marked lost */
3614 tcp_rate_gen(sk, delivered, lost, sack_state.rate); 3622 tcp_rate_gen(sk, delivered, lost, is_sack_reneg, sack_state.rate);
3615 tcp_cong_control(sk, ack, delivered, flag, sack_state.rate); 3623 tcp_cong_control(sk, ack, delivered, flag, sack_state.rate);
3616 tcp_xmit_recovery(sk, rexmit); 3624 tcp_xmit_recovery(sk, rexmit);
3617 return 1; 3625 return 1;