Once tp->rcv_wnd carries paired snapshot semantics, every write of the advertised window has to refresh the snapshot at the same time.
Convert the active-open, passive-open, and normal advertised-window update sites to use tcp_set_rcv_wnd(). This keeps new sockets and later window advertisements initialized with a valid advertise-time basis before the receive-memory logic starts consuming it. Signed-off-by: Wesley Atwell <[email protected]> --- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index dafb63b923d0..ae8a466b5298 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -603,7 +603,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, newtp->rx_opt.sack_ok = ireq->sack_ok; newtp->window_clamp = req->rsk_window_clamp; newtp->rcv_ssthresh = req->rsk_rcv_wnd; - newtp->rcv_wnd = req->rsk_rcv_wnd; + tcp_set_rcv_wnd(newtp, req->rsk_rcv_wnd); newtp->rx_opt.wscale_ok = ireq->wscale_ok; if (newtp->rx_opt.wscale_ok) { newtp->rx_opt.snd_wscale = ireq->snd_wscale; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 326b58ff1118..c1b94d67d8fe 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -291,7 +291,7 @@ static u16 tcp_select_window(struct sock *sk) */ if (unlikely(inet_csk(sk)->icsk_ack.pending & ICSK_ACK_NOMEM)) { tp->pred_flags = 0; - tp->rcv_wnd = 0; + tcp_set_rcv_wnd(tp, 0); tp->rcv_wup = tp->rcv_nxt; return 0; } @@ -314,7 +314,7 @@ static u16 tcp_select_window(struct sock *sk) } } - tp->rcv_wnd = new_win; + tcp_set_rcv_wnd(tp, new_win); tp->rcv_wup = tp->rcv_nxt; /* Make sure we do not exceed the maximum possible @@ -4150,6 +4150,10 @@ static void tcp_connect_init(struct sock *sk) READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_window_scaling), &rcv_wscale, rcv_wnd); + /* tcp_select_initial_window() filled tp->rcv_wnd through its out-param, + * so snapshot the scaling_ratio we will use for that initial rwnd. + */ + tcp_set_rcv_wnd(tp, tp->rcv_wnd); tp->rx_opt.rcv_wscale = rcv_wscale; tp->rcv_ssthresh = tp->rcv_wnd; -- 2.34.1
