Skip to content

Commit a2cbb16

Browse files
Subash Abhinov Kasiviswanathandavem330
authored andcommitted
tcp: Update window clamping condition
This patch is based on the discussions between Neal Cardwell and Eric Dumazet in the link https://lore.kernel.org/netdev/[email protected]/ It was correctly pointed out that tp->window_clamp would not be updated in cases where net.ipv4.tcp_moderate_rcvbuf=0 or if (copied <= tp->rcvq_space.space). While it is expected for most setups to leave the sysctl enabled, the latter condition may not end up hitting depending on the TCP receive queue size and the pattern of arriving data. The updated check should be hit only on initial MSS update from TCP_MIN_MSS to measured MSS value and subsequently if there was an update to a larger value. Fixes: 05f76b2 ("tcp: Adjust clamping window for applications specifying SO_RCVBUF") Signed-off-by: Sean Tranchetti <[email protected]> Signed-off-by: Subash Abhinov Kasiviswanathan <[email protected]> Acked-by: Neal Cardwell <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 655111b commit a2cbb16

File tree

1 file changed

+12
-16
lines changed

1 file changed

+12
-16
lines changed

net/ipv4/tcp_input.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,14 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
238238
*/
239239
if (unlikely(len != icsk->icsk_ack.rcv_mss)) {
240240
u64 val = (u64)skb->len << TCP_RMEM_TO_WIN_SCALE;
241+
u8 old_ratio = tcp_sk(sk)->scaling_ratio;
241242

242243
do_div(val, skb->truesize);
243244
tcp_sk(sk)->scaling_ratio = val ? val : 1;
245+
246+
if (old_ratio != tcp_sk(sk)->scaling_ratio)
247+
WRITE_ONCE(tcp_sk(sk)->window_clamp,
248+
tcp_win_from_space(sk, sk->sk_rcvbuf));
244249
}
245250
icsk->icsk_ack.rcv_mss = min_t(unsigned int, len,
246251
tcp_sk(sk)->advmss);
@@ -754,7 +759,8 @@ void tcp_rcv_space_adjust(struct sock *sk)
754759
* <prev RTT . ><current RTT .. ><next RTT .... >
755760
*/
756761

757-
if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_moderate_rcvbuf)) {
762+
if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_moderate_rcvbuf) &&
763+
!(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
758764
u64 rcvwin, grow;
759765
int rcvbuf;
760766

@@ -770,22 +776,12 @@ void tcp_rcv_space_adjust(struct sock *sk)
770776

771777
rcvbuf = min_t(u64, tcp_space_from_win(sk, rcvwin),
772778
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]));
773-
if (!(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
774-
if (rcvbuf > sk->sk_rcvbuf) {
775-
WRITE_ONCE(sk->sk_rcvbuf, rcvbuf);
776-
777-
/* Make the window clamp follow along. */
778-
WRITE_ONCE(tp->window_clamp,
779-
tcp_win_from_space(sk, rcvbuf));
780-
}
781-
} else {
782-
/* Make the window clamp follow along while being bounded
783-
* by SO_RCVBUF.
784-
*/
785-
int clamp = tcp_win_from_space(sk, min(rcvbuf, sk->sk_rcvbuf));
779+
if (rcvbuf > sk->sk_rcvbuf) {
780+
WRITE_ONCE(sk->sk_rcvbuf, rcvbuf);
786781

787-
if (clamp > tp->window_clamp)
788-
WRITE_ONCE(tp->window_clamp, clamp);
782+
/* Make the window clamp follow along. */
783+
WRITE_ONCE(tp->window_clamp,
784+
tcp_win_from_space(sk, rcvbuf));
789785
}
790786
}
791787
tp->rcvq_space.space = copied;

0 commit comments

Comments
 (0)