Skip to content

Commit f410cbe

Browse files
edumazetkuba-moo
authored andcommitted
tcp: annotate data-races around tp->window_clamp
tp->window_clamp can be read locklessly, add READ_ONCE() and WRITE_ONCE() annotations. Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Jason Xing <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 571faef commit f410cbe

File tree

7 files changed

+29
-23
lines changed

7 files changed

+29
-23
lines changed

net/ipv4/syncookies.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
462462
}
463463

464464
/* Try to redo what tcp_v4_send_synack did. */
465-
req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW);
465+
req->rsk_window_clamp = READ_ONCE(tp->window_clamp) ? :
466+
dst_metric(&rt->dst, RTAX_WINDOW);
466467
/* limit the window selection if the user enforce a smaller rx buffer */
467468
full_space = tcp_full_space(sk);
468469
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&

net/ipv4/tcp.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,7 +1721,7 @@ int tcp_set_rcvlowat(struct sock *sk, int val)
17211721
space = tcp_space_from_win(sk, val);
17221722
if (space > sk->sk_rcvbuf) {
17231723
WRITE_ONCE(sk->sk_rcvbuf, space);
1724-
tcp_sk(sk)->window_clamp = val;
1724+
WRITE_ONCE(tcp_sk(sk)->window_clamp, val);
17251725
}
17261726
return 0;
17271727
}
@@ -3379,7 +3379,7 @@ int tcp_set_window_clamp(struct sock *sk, int val)
33793379
if (!val) {
33803380
if (sk->sk_state != TCP_CLOSE)
33813381
return -EINVAL;
3382-
tp->window_clamp = 0;
3382+
WRITE_ONCE(tp->window_clamp, 0);
33833383
} else {
33843384
u32 new_rcv_ssthresh, old_window_clamp = tp->window_clamp;
33853385
u32 new_window_clamp = val < SOCK_MIN_RCVBUF / 2 ?
@@ -3388,7 +3388,7 @@ int tcp_set_window_clamp(struct sock *sk, int val)
33883388
if (new_window_clamp == old_window_clamp)
33893389
return 0;
33903390

3391-
tp->window_clamp = new_window_clamp;
3391+
WRITE_ONCE(tp->window_clamp, new_window_clamp);
33923392
if (new_window_clamp < old_window_clamp) {
33933393
/* need to apply the reserved mem provisioning only
33943394
* when shrinking the window clamp
@@ -4057,7 +4057,7 @@ int do_tcp_getsockopt(struct sock *sk, int level,
40574057
TCP_RTO_MAX / HZ);
40584058
break;
40594059
case TCP_WINDOW_CLAMP:
4060-
val = tp->window_clamp;
4060+
val = READ_ONCE(tp->window_clamp);
40614061
break;
40624062
case TCP_INFO: {
40634063
struct tcp_info info;

net/ipv4/tcp_input.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -563,19 +563,20 @@ static void tcp_init_buffer_space(struct sock *sk)
563563
maxwin = tcp_full_space(sk);
564564

565565
if (tp->window_clamp >= maxwin) {
566-
tp->window_clamp = maxwin;
566+
WRITE_ONCE(tp->window_clamp, maxwin);
567567

568568
if (tcp_app_win && maxwin > 4 * tp->advmss)
569-
tp->window_clamp = max(maxwin -
570-
(maxwin >> tcp_app_win),
571-
4 * tp->advmss);
569+
WRITE_ONCE(tp->window_clamp,
570+
max(maxwin - (maxwin >> tcp_app_win),
571+
4 * tp->advmss));
572572
}
573573

574574
/* Force reservation of one segment. */
575575
if (tcp_app_win &&
576576
tp->window_clamp > 2 * tp->advmss &&
577577
tp->window_clamp + tp->advmss > maxwin)
578-
tp->window_clamp = max(2 * tp->advmss, maxwin - tp->advmss);
578+
WRITE_ONCE(tp->window_clamp,
579+
max(2 * tp->advmss, maxwin - tp->advmss));
579580

580581
tp->rcv_ssthresh = min(tp->rcv_ssthresh, tp->window_clamp);
581582
tp->snd_cwnd_stamp = tcp_jiffies32;
@@ -773,7 +774,8 @@ void tcp_rcv_space_adjust(struct sock *sk)
773774
WRITE_ONCE(sk->sk_rcvbuf, rcvbuf);
774775

775776
/* Make the window clamp follow along. */
776-
tp->window_clamp = tcp_win_from_space(sk, rcvbuf);
777+
WRITE_ONCE(tp->window_clamp,
778+
tcp_win_from_space(sk, rcvbuf));
777779
}
778780
}
779781
tp->rcvq_space.space = copied;
@@ -6426,7 +6428,8 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
64266428

64276429
if (!tp->rx_opt.wscale_ok) {
64286430
tp->rx_opt.snd_wscale = tp->rx_opt.rcv_wscale = 0;
6429-
tp->window_clamp = min(tp->window_clamp, 65535U);
6431+
WRITE_ONCE(tp->window_clamp,
6432+
min(tp->window_clamp, 65535U));
64306433
}
64316434

64326435
if (tp->rx_opt.saw_tstamp) {

net/ipv4/tcp_output.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,16 +203,17 @@ static inline void tcp_event_ack_sent(struct sock *sk, u32 rcv_nxt)
203203
* This MUST be enforced by all callers.
204204
*/
205205
void tcp_select_initial_window(const struct sock *sk, int __space, __u32 mss,
206-
__u32 *rcv_wnd, __u32 *window_clamp,
206+
__u32 *rcv_wnd, __u32 *__window_clamp,
207207
int wscale_ok, __u8 *rcv_wscale,
208208
__u32 init_rcv_wnd)
209209
{
210210
unsigned int space = (__space < 0 ? 0 : __space);
211+
u32 window_clamp = READ_ONCE(*__window_clamp);
211212

212213
/* If no clamp set the clamp to the max possible scaled window */
213-
if (*window_clamp == 0)
214-
(*window_clamp) = (U16_MAX << TCP_MAX_WSCALE);
215-
space = min(*window_clamp, space);
214+
if (window_clamp == 0)
215+
window_clamp = (U16_MAX << TCP_MAX_WSCALE);
216+
space = min(window_clamp, space);
216217

217218
/* Quantize space offering to a multiple of mss if possible. */
218219
if (space > mss)
@@ -239,12 +240,13 @@ void tcp_select_initial_window(const struct sock *sk, int __space, __u32 mss,
239240
/* Set window scaling on max possible window */
240241
space = max_t(u32, space, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]));
241242
space = max_t(u32, space, READ_ONCE(sysctl_rmem_max));
242-
space = min_t(u32, space, *window_clamp);
243+
space = min_t(u32, space, window_clamp);
243244
*rcv_wscale = clamp_t(int, ilog2(space) - 15,
244245
0, TCP_MAX_WSCALE);
245246
}
246247
/* Set the clamp no higher than max representable value */
247-
(*window_clamp) = min_t(__u32, U16_MAX << (*rcv_wscale), *window_clamp);
248+
WRITE_ONCE(*__window_clamp,
249+
min_t(__u32, U16_MAX << (*rcv_wscale), window_clamp));
248250
}
249251
EXPORT_SYMBOL(tcp_select_initial_window);
250252

@@ -3855,15 +3857,15 @@ static void tcp_connect_init(struct sock *sk)
38553857
tcp_ca_dst_init(sk, dst);
38563858

38573859
if (!tp->window_clamp)
3858-
tp->window_clamp = dst_metric(dst, RTAX_WINDOW);
3860+
WRITE_ONCE(tp->window_clamp, dst_metric(dst, RTAX_WINDOW));
38593861
tp->advmss = tcp_mss_clamp(tp, dst_metric_advmss(dst));
38603862

38613863
tcp_initialize_rcv_mss(sk);
38623864

38633865
/* limit the window selection if the user enforce a smaller rx buffer */
38643866
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&
38653867
(tp->window_clamp > tcp_full_space(sk) || tp->window_clamp == 0))
3866-
tp->window_clamp = tcp_full_space(sk);
3868+
WRITE_ONCE(tp->window_clamp, tcp_full_space(sk));
38673869

38683870
rcv_wnd = tcp_rwnd_init_bpf(sk);
38693871
if (rcv_wnd == 0)

net/ipv6/syncookies.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
246246
}
247247
}
248248

249-
req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
249+
req->rsk_window_clamp = READ_ONCE(tp->window_clamp) ? :dst_metric(dst, RTAX_WINDOW);
250250
/* limit the window selection if the user enforce a smaller rx buffer */
251251
full_space = tcp_full_space(sk);
252252
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&

net/mptcp/protocol.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2056,7 +2056,7 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied)
20562056
ssk = mptcp_subflow_tcp_sock(subflow);
20572057
slow = lock_sock_fast(ssk);
20582058
WRITE_ONCE(ssk->sk_rcvbuf, rcvbuf);
2059-
tcp_sk(ssk)->window_clamp = window_clamp;
2059+
WRITE_ONCE(tcp_sk(ssk)->window_clamp, window_clamp);
20602060
tcp_cleanup_rbuf(ssk, 1);
20612061
unlock_sock_fast(ssk, slow);
20622062
}

net/mptcp/sockopt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1523,7 +1523,7 @@ int mptcp_set_rcvlowat(struct sock *sk, int val)
15231523

15241524
slow = lock_sock_fast(ssk);
15251525
WRITE_ONCE(ssk->sk_rcvbuf, space);
1526-
tcp_sk(ssk)->window_clamp = val;
1526+
WRITE_ONCE(tcp_sk(ssk)->window_clamp, val);
15271527
unlock_sock_fast(ssk, slow);
15281528
}
15291529
return 0;

0 commit comments

Comments
 (0)