diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
| -rw-r--r-- | net/ipv4/tcp_input.c | 28 | 
1 files changed, 12 insertions, 16 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e2b9583ed96a..e37488d3453f 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -238,9 +238,14 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)  		 */  		if (unlikely(len != icsk->icsk_ack.rcv_mss)) {  			u64 val = (u64)skb->len << TCP_RMEM_TO_WIN_SCALE; +			u8 old_ratio = tcp_sk(sk)->scaling_ratio;  			do_div(val, skb->truesize);  			tcp_sk(sk)->scaling_ratio = val ? val : 1; + +			if (old_ratio != tcp_sk(sk)->scaling_ratio) +				WRITE_ONCE(tcp_sk(sk)->window_clamp, +					   tcp_win_from_space(sk, sk->sk_rcvbuf));  		}  		icsk->icsk_ack.rcv_mss = min_t(unsigned int, len,  					       tcp_sk(sk)->advmss); @@ -754,7 +759,8 @@ void tcp_rcv_space_adjust(struct sock *sk)  	 * <prev RTT . ><current RTT .. ><next RTT .... >  	 */ -	if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_moderate_rcvbuf)) { +	if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_moderate_rcvbuf) && +	    !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {  		u64 rcvwin, grow;  		int rcvbuf; @@ -770,22 +776,12 @@ void tcp_rcv_space_adjust(struct sock *sk)  		rcvbuf = min_t(u64, tcp_space_from_win(sk, rcvwin),  			       READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2])); -		if (!(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) { -			if (rcvbuf > sk->sk_rcvbuf) { -				WRITE_ONCE(sk->sk_rcvbuf, rcvbuf); - -				/* Make the window clamp follow along.  */ -				WRITE_ONCE(tp->window_clamp, -					   tcp_win_from_space(sk, rcvbuf)); -			} -		} else { -			/* Make the window clamp follow along while being bounded -			 * by SO_RCVBUF. -			 */ -			int clamp = tcp_win_from_space(sk, min(rcvbuf, sk->sk_rcvbuf)); +		if (rcvbuf > sk->sk_rcvbuf) { +			WRITE_ONCE(sk->sk_rcvbuf, rcvbuf); -			if (clamp > tp->window_clamp) -				WRITE_ONCE(tp->window_clamp, clamp); +			/* Make the window clamp follow along.  */ +			WRITE_ONCE(tp->window_clamp, +				   tcp_win_from_space(sk, rcvbuf));  		}  	}  	tp->rcvq_space.space = copied;  |