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


Reply via email to