diff options
author | Eric Dumazet <edumazet@google.com> | 2015-09-25 10:39:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-09-25 16:00:36 -0400 |
commit | b1964b5fce389a5660139ca39c25ff294da07b4f (patch) | |
tree | 9e165bbd7f65719fa9f1330fe33edfa3f49b3e67 /net/ipv4/tcp_minisocks.c | |
parent | b40cf18ef7961b6d67732e234780586590510ce1 (diff) |
tcp: constify tcp_openreq_init_rwin()
Soon, listener socket wont be locked when tcp_openreq_init_rwin()
is called. We need to read socket fields once, as their value
could change under us.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 85830bb92d04..e0a87c238882 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -362,27 +362,35 @@ void tcp_twsk_destructor(struct sock *sk) | |||
362 | } | 362 | } |
363 | EXPORT_SYMBOL_GPL(tcp_twsk_destructor); | 363 | EXPORT_SYMBOL_GPL(tcp_twsk_destructor); |
364 | 364 | ||
365 | /* Warning : This function is called without sk_listener being locked. | ||
366 | * Be sure to read socket fields once, as their value could change under us. | ||
367 | */ | ||
365 | void tcp_openreq_init_rwin(struct request_sock *req, | 368 | void tcp_openreq_init_rwin(struct request_sock *req, |
366 | struct sock *sk, struct dst_entry *dst) | 369 | const struct sock *sk_listener, |
370 | const struct dst_entry *dst) | ||
367 | { | 371 | { |
368 | struct inet_request_sock *ireq = inet_rsk(req); | 372 | struct inet_request_sock *ireq = inet_rsk(req); |
369 | struct tcp_sock *tp = tcp_sk(sk); | 373 | const struct tcp_sock *tp = tcp_sk(sk_listener); |
370 | __u8 rcv_wscale; | 374 | u16 user_mss = READ_ONCE(tp->rx_opt.user_mss); |
375 | int full_space = tcp_full_space(sk_listener); | ||
371 | int mss = dst_metric_advmss(dst); | 376 | int mss = dst_metric_advmss(dst); |
377 | u32 window_clamp; | ||
378 | __u8 rcv_wscale; | ||
372 | 379 | ||
373 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) | 380 | if (user_mss && user_mss < mss) |
374 | mss = tp->rx_opt.user_mss; | 381 | mss = user_mss; |
375 | 382 | ||
383 | window_clamp = READ_ONCE(tp->window_clamp); | ||
376 | /* Set this up on the first call only */ | 384 | /* Set this up on the first call only */ |
377 | req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); | 385 | req->window_clamp = window_clamp ? : dst_metric(dst, RTAX_WINDOW); |
378 | 386 | ||
379 | /* limit the window selection if the user enforce a smaller rx buffer */ | 387 | /* limit the window selection if the user enforce a smaller rx buffer */ |
380 | if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && | 388 | if (sk_listener->sk_userlocks & SOCK_RCVBUF_LOCK && |
381 | (req->window_clamp > tcp_full_space(sk) || req->window_clamp == 0)) | 389 | (req->window_clamp > full_space || req->window_clamp == 0)) |
382 | req->window_clamp = tcp_full_space(sk); | 390 | req->window_clamp = full_space; |
383 | 391 | ||
384 | /* tcp_full_space because it is guaranteed to be the first packet */ | 392 | /* tcp_full_space because it is guaranteed to be the first packet */ |
385 | tcp_select_initial_window(tcp_full_space(sk), | 393 | tcp_select_initial_window(full_space, |
386 | mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), | 394 | mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), |
387 | &req->rcv_wnd, | 395 | &req->rcv_wnd, |
388 | &req->window_clamp, | 396 | &req->window_clamp, |