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.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 734cfc8ff76e..45f750e85714 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -508,9 +508,6 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
508 u32 new_sample = tp->rcv_rtt_est.rtt_us; 508 u32 new_sample = tp->rcv_rtt_est.rtt_us;
509 long m = sample; 509 long m = sample;
510 510
511 if (m == 0)
512 m = 1;
513
514 if (new_sample != 0) { 511 if (new_sample != 0) {
515 /* If we sample in larger samples in the non-timestamp 512 /* If we sample in larger samples in the non-timestamp
516 * case, we could grossly overestimate the RTT especially 513 * case, we could grossly overestimate the RTT especially
@@ -547,6 +544,8 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp)
547 if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq)) 544 if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq))
548 return; 545 return;
549 delta_us = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcv_rtt_est.time); 546 delta_us = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcv_rtt_est.time);
547 if (!delta_us)
548 delta_us = 1;
550 tcp_rcv_rtt_update(tp, delta_us, 1); 549 tcp_rcv_rtt_update(tp, delta_us, 1);
551 550
552new_measure: 551new_measure:
@@ -563,8 +562,11 @@ static inline void tcp_rcv_rtt_measure_ts(struct sock *sk,
563 (TCP_SKB_CB(skb)->end_seq - 562 (TCP_SKB_CB(skb)->end_seq -
564 TCP_SKB_CB(skb)->seq >= inet_csk(sk)->icsk_ack.rcv_mss)) { 563 TCP_SKB_CB(skb)->seq >= inet_csk(sk)->icsk_ack.rcv_mss)) {
565 u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr; 564 u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr;
566 u32 delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ); 565 u32 delta_us;
567 566
567 if (!delta)
568 delta = 1;
569 delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ);
568 tcp_rcv_rtt_update(tp, delta_us, 0); 570 tcp_rcv_rtt_update(tp, delta_us, 0);
569 } 571 }
570} 572}
@@ -579,6 +581,7 @@ void tcp_rcv_space_adjust(struct sock *sk)
579 int time; 581 int time;
580 int copied; 582 int copied;
581 583
584 tcp_mstamp_refresh(tp);
582 time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time); 585 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) 586 if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0)
584 return; 587 return;
@@ -1941,6 +1944,8 @@ void tcp_enter_loss(struct sock *sk)
1941 if (is_reneg) { 1944 if (is_reneg) {
1942 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSACKRENEGING); 1945 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSACKRENEGING);
1943 tp->sacked_out = 0; 1946 tp->sacked_out = 0;
1947 /* Mark SACK reneging until we recover from this loss event. */
1948 tp->is_sack_reneg = 1;
1944 } 1949 }
1945 tcp_clear_all_retrans_hints(tp); 1950 tcp_clear_all_retrans_hints(tp);
1946 1951
@@ -2326,6 +2331,7 @@ static void tcp_undo_cwnd_reduction(struct sock *sk, bool unmark_loss)
2326 } 2331 }
2327 tp->snd_cwnd_stamp = tcp_jiffies32; 2332 tp->snd_cwnd_stamp = tcp_jiffies32;
2328 tp->undo_marker = 0; 2333 tp->undo_marker = 0;
2334 tp->rack.advanced = 1; /* Force RACK to re-exam losses */
2329} 2335}
2330 2336
2331static inline bool tcp_may_undo(const struct tcp_sock *tp) 2337static inline bool tcp_may_undo(const struct tcp_sock *tp)
@@ -2364,6 +2370,7 @@ static bool tcp_try_undo_recovery(struct sock *sk)
2364 return true; 2370 return true;
2365 } 2371 }
2366 tcp_set_ca_state(sk, TCP_CA_Open); 2372 tcp_set_ca_state(sk, TCP_CA_Open);
2373 tp->is_sack_reneg = 0;
2367 return false; 2374 return false;
2368} 2375}
2369 2376
@@ -2397,8 +2404,10 @@ static bool tcp_try_undo_loss(struct sock *sk, bool frto_undo)
2397 NET_INC_STATS(sock_net(sk), 2404 NET_INC_STATS(sock_net(sk),
2398 LINUX_MIB_TCPSPURIOUSRTOS); 2405 LINUX_MIB_TCPSPURIOUSRTOS);
2399 inet_csk(sk)->icsk_retransmits = 0; 2406 inet_csk(sk)->icsk_retransmits = 0;
2400 if (frto_undo || tcp_is_sack(tp)) 2407 if (frto_undo || tcp_is_sack(tp)) {
2401 tcp_set_ca_state(sk, TCP_CA_Open); 2408 tcp_set_ca_state(sk, TCP_CA_Open);
2409 tp->is_sack_reneg = 0;
2410 }
2402 return true; 2411 return true;
2403 } 2412 }
2404 return false; 2413 return false;
@@ -3495,6 +3504,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3495 struct tcp_sacktag_state sack_state; 3504 struct tcp_sacktag_state sack_state;
3496 struct rate_sample rs = { .prior_delivered = 0 }; 3505 struct rate_sample rs = { .prior_delivered = 0 };
3497 u32 prior_snd_una = tp->snd_una; 3506 u32 prior_snd_una = tp->snd_una;
3507 bool is_sack_reneg = tp->is_sack_reneg;
3498 u32 ack_seq = TCP_SKB_CB(skb)->seq; 3508 u32 ack_seq = TCP_SKB_CB(skb)->seq;
3499 u32 ack = TCP_SKB_CB(skb)->ack_seq; 3509 u32 ack = TCP_SKB_CB(skb)->ack_seq;
3500 bool is_dupack = false; 3510 bool is_dupack = false;
@@ -3611,7 +3621,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3611 3621
3612 delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */ 3622 delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */
3613 lost = tp->lost - lost; /* freshly marked lost */ 3623 lost = tp->lost - lost; /* freshly marked lost */
3614 tcp_rate_gen(sk, delivered, lost, sack_state.rate); 3624 tcp_rate_gen(sk, delivered, lost, is_sack_reneg, sack_state.rate);
3615 tcp_cong_control(sk, ack, delivered, flag, sack_state.rate); 3625 tcp_cong_control(sk, ack, delivered, flag, sack_state.rate);
3616 tcp_xmit_recovery(sk, rexmit); 3626 tcp_xmit_recovery(sk, rexmit);
3617 return 1; 3627 return 1;