| @@ -664,10 +664,12 @@ EXPORT_IPV6_MOD(tcp_initialize_rcv_mss); · 663 unmodified lines |
| 664 | 664 | */ |
| 665 | 665 | static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep) |
| 666 | 666 | { |
| 667 | | − u32 new_sample = tp->rcv_rtt_est.rtt_us; |
| 668 | | − long m = sample; |
| 667 | + u32 new_sample, old_sample = tp->rcv_rtt_est.rtt_us; |
| 668 | + long m = sample << 3; |
| 669 | 669 | |
| 670 | | − if (new_sample != 0) { |
| 670 | + if (old_sample == 0 || m < old_sample) { |
| 671 | + new_sample = m; |
| 672 | + } else { |
| 671 | 673 | /* If we sample in larger samples in the non-timestamp |
| 672 | 674 | * case, we could grossly overestimate the RTT especially |
| 673 | 675 | * with chatty applications or bulk transfer apps which |
| @@ -678,17 +680,12 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep) · 4 unmodified lines |
| 678 | 680 | * else with timestamps disabled convergence takes too |
| 679 | 681 | * long. |
| 680 | 682 | */ |
| 681 | | − if (!win_dep) { |
| 682 | | − m -= (new_sample >> 3); |
| 683 | | − new_sample += m; |
| 684 | | − } else { |
| 685 | | − m <<= 3; |
| 686 | | − if (m < new_sample) |
| 687 | | − new_sample = m; |
| 688 | | − } |
| 689 | | − } else { |
| 690 | | − /* No previous measure. */ |
| 691 | | − new_sample = m << 3; |
| 683 | + if (win_dep) |
| 684 | + return; |
| 685 | + /* Do not use this sample if receive queue is not empty. */ |
| 686 | + if (tp->rcv_nxt != tp->copied_seq) |
| 687 | + return; |
| 688 | + new_sample = old_sample - (old_sample >> 3) + sample; |
| 692 | 689 | } |
| 693 | 690 | |
| 694 | 691 | tp->rcv_rtt_est.rtt_us = new_sample; |
| @@ -712,7 +709,7 @@ new_measure: · 17 unmodified lines |
| 712 | 709 | tp->rcv_rtt_est.time = tp->tcp_mstamp; |
| 713 | 710 | } |
| 714 | 711 | |
| 715 | | −static s32 tcp_rtt_tsopt_us(const struct tcp_sock *tp) |
| 712 | +static s32 tcp_rtt_tsopt_us(const struct tcp_sock *tp, u32 min_delta) |
| 716 | 713 | { |
| 717 | 714 | u32 delta, delta_us; |
| 718 | 715 | |
| @@ -722,7 +719,7 @@ static s32 tcp_rtt_tsopt_us(const struct tcp_sock *tp) · 3 unmodified lines |
| 722 | 719 | |
| 723 | 720 | if (likely(delta < INT_MAX / (USEC_PER_SEC / TCP_TS_HZ))) { |
| 724 | 721 | if (!delta) |
| 725 | | − delta = 1; |
| 722 | + delta = min_delta; |
| 726 | 723 | delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ); |
| 727 | 724 | return delta_us; |
| 728 | 725 | } |
| @@ -740,13 +737,39 @@ static inline void tcp_rcv_rtt_measure_ts(struct sock *sk, · 11 unmodified lines |
| 740 | 737 | |
| 741 | 738 | if (TCP_SKB_CB(skb)->end_seq - |
| 742 | 739 | TCP_SKB_CB(skb)->seq >= inet_csk(sk)->icsk_ack.rcv_mss) { |
| 743 | | − s32 delta = tcp_rtt_tsopt_us(tp); |
| 740 | + s32 delta = tcp_rtt_tsopt_us(tp, 0); |
| 744 | 741 | |
| 745 | | − if (delta >= 0) |
| 742 | + if (delta > 0) |
| 746 | 743 | tcp_rcv_rtt_update(tp, delta, 0); |
| 747 | 744 | } |
| 748 | 745 | } |
| 749 | 746 | |
| 747 | +static void tcp_rcvbuf_grow(struct sock *sk) |
| 748 | +{ |
| 749 | + const struct net *net = sock_net(sk); |
| 750 | + struct tcp_sock *tp = tcp_sk(sk); |
| 751 | + int rcvwin, rcvbuf, cap; |
| 752 | + |
| 753 | + if (!READ_ONCE(net->ipv4.sysctl_tcp_moderate_rcvbuf) || |
| 754 | + (sk->sk_userlocks & SOCK_RCVBUF_LOCK)) |
| 755 | + return; |
| 756 | + |
| 757 | + /* slow start: allow the sender to double its rate. */ |
| 758 | + rcvwin = tp->rcvq_space.space << 1; |
| 759 | + |
| 760 | + if (!RB_EMPTY_ROOT(&tp->out_of_order_queue)) |
| 761 | + rcvwin += TCP_SKB_CB(tp->ooo_last_skb)->end_seq - tp->rcv_nxt; |
| 762 | + |
| 763 | + cap = READ_ONCE(net->ipv4.sysctl_tcp_rmem[2]); |
| 764 | + |
| 765 | + rcvbuf = min_t(u32, tcp_space_from_win(sk, rcvwin), cap); |
| 766 | + if (rcvbuf > sk->sk_rcvbuf) { |
| 767 | + WRITE_ONCE(sk->sk_rcvbuf, rcvbuf); |
| 768 | + /* Make the window clamp follow along. */ |
| 769 | + WRITE_ONCE(tp->window_clamp, |
| 770 | + tcp_win_from_space(sk, rcvbuf)); |
| 771 | + } |
| 772 | +} |
| 750 | 773 | /* |
| 751 | 774 | * This function should be called every time data is copied to user space. |
| 752 | 775 | * It calculates the appropriate TCP receive buffer space. |
| @@ -754,8 +777,7 @@ static inline void tcp_rcv_rtt_measure_ts(struct sock *sk, · 1 unmodified line |
| 754 | 777 | void tcp_rcv_space_adjust(struct sock *sk) |
| 755 | 778 | { |
| 756 | 779 | struct tcp_sock *tp = tcp_sk(sk); |
| 757 | | − u32 copied; |
| 758 | | − int time; |
| 780 | + int time, inq, copied; |
| 759 | 781 | |
| 760 | 782 | trace_tcp_rcv_space_adjust(sk); |
| 761 | 783 | |
| @@ -766,45 +788,18 @@ void tcp_rcv_space_adjust(struct sock *sk) · 4 unmodified lines |
| 766 | 788 | |
| 767 | 789 | /* Number of bytes copied to user in last RTT */ |
| 768 | 790 | copied = tp->copied_seq - tp->rcvq_space.seq; |
| 791 | + /* Number of bytes in receive queue. */ |
| 792 | + inq = tp->rcv_nxt - tp->copied_seq; |
| 793 | + copied -= inq; |
| 769 | 794 | if (copied <= tp->rcvq_space.space) |
| 770 | 795 | goto new_measure; |
| 771 | 796 | |
| 772 | | − /* A bit of theory : |
| 773 | | − * copied = bytes received in previous RTT, our base window |
| 774 | | − * To cope with packet losses, we need a 2x factor |
| 775 | | − * To cope with slow start, and sender growing its cwin by 100 % |
| 776 | | − * every RTT, we need a 4x factor, because the ACK we are sending |
| 777 | | − * now is for the next RTT, not the current one : |
| 778 | | − * <prev RTT . ><current RTT .. ><next RTT .... > |
| 779 | | − */ |
| 780 | | − |
| 781 | | − if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_moderate_rcvbuf) && |
| 782 | | − !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) { |
| 783 | | − u64 rcvwin, grow; |
| 784 | | − int rcvbuf; |
| 785 | | − |
| 786 | | − /* minimal window to cope with packet losses, assuming |
| 787 | | − * steady state. Add some cushion because of small variations. |
| 788 | | − */ |
| 789 | | − rcvwin = ((u64)copied << 1) + 16 * tp->advmss; |
| 797 | + trace_tcp_rcvbuf_grow(sk, time); |
| 790 | 798 | |
| 791 | | − /* Accommodate for sender rate increase (eg. slow start) */ |
| 792 | | − grow = rcvwin * (copied - tp->rcvq_space.space); |
| 793 | | − do_div(grow, tp->rcvq_space.space); |
| 794 | | − rcvwin += (grow << 1); |
| 795 | | − |
| 796 | | − rcvbuf = min_t(u64, tcp_space_from_win(sk, rcvwin), |
| 797 | | − READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2])); |
| 798 | | − if (rcvbuf > sk->sk_rcvbuf) { |
| 799 | | − WRITE_ONCE(sk->sk_rcvbuf, rcvbuf); |
| 800 | | − |
| 801 | | − /* Make the window clamp follow along. */ |
| 802 | | − WRITE_ONCE(tp->window_clamp, |
| 803 | | − tcp_win_from_space(sk, rcvbuf)); |
| 804 | | − } |
| 805 | | − } |
| 806 | 799 | tp->rcvq_space.space = copied; |
| 807 | 800 | |
| 801 | + tcp_rcvbuf_grow(sk); |
| 802 | + |
| 808 | 803 | new_measure: |
| 809 | 804 | tp->rcvq_space.seq = tp->copied_seq; |
| 810 | 805 | tp->rcvq_space.time = tp->tcp_mstamp; |
| @@ -3226,7 +3221,7 @@ static bool tcp_ack_update_rtt(struct sock *sk, const int flag, · 2415 unmodified lines |
| 3226 | 3221 | */ |
| 3227 | 3222 | if (seq_rtt_us < 0 && tp->rx_opt.saw_tstamp && |
| 3228 | 3223 | tp->rx_opt.rcv_tsecr && flag & FLAG_ACKED) |
| 3229 | | − seq_rtt_us = ca_rtt_us = tcp_rtt_tsopt_us(tp); |
| 3224 | + seq_rtt_us = ca_rtt_us = tcp_rtt_tsopt_us(tp, 1); |
| 3230 | 3225 | |
| 3231 | 3226 | rs->rtt_us = ca_rtt_us; /* RTT of last (S)ACKed packet (or -1) */ |
| 3232 | 3227 | if (seq_rtt_us < 0) |
| @@ -5173,6 +5168,7 @@ end: · 1940 unmodified lines |
| 5173 | 5168 | skb_condense(skb); |
| 5174 | 5169 | skb_set_owner_r(skb, sk); |
| 5175 | 5170 | } |
| 5171 | + tcp_rcvbuf_grow(sk); |
| 5176 | 5172 | } |
| 5177 | 5173 | |
| 5178 | 5174 | static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, |
| @@ -6873,6 +6869,9 @@ tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) · 1694 unmodified lines |
| 6873 | 6869 | if (!tp->srtt_us) |
| 6874 | 6870 | tcp_synack_rtt_meas(sk, req); |
| 6875 | 6871 | |
| 6872 | + if (tp->rx_opt.tstamp_ok) |
| 6873 | + tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; |
| 6874 | + |
| 6876 | 6875 | if (req) { |
| 6877 | 6876 | tcp_rcv_synrecv_state_fastopen(sk); |
| 6878 | 6877 | } else { |
| @@ -6898,9 +6897,6 @@ tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) · 19 unmodified lines |
| 6898 | 6897 | tp->snd_wnd = ntohs(th->window) << tp->rx_opt.snd_wscale; |
| 6899 | 6898 | tcp_init_wl(tp, TCP_SKB_CB(skb)->seq); |
| 6900 | 6899 | |
| 6901 | | − if (tp->rx_opt.tstamp_ok) |
| 6902 | | − tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; |
| 6903 | | − |
| 6904 | 6900 | if (!inet_csk(sk)->icsk_ca_ops->cong_control) |
| 6905 | 6901 | tcp_update_pacing_rate(sk); |
| 6906 | 6902 | |