Skip to content

Commit 9af0620

Browse files
committed
Merge branch 'net-sysctl-races-part-6'
Kuniyuki Iwashima says: ==================== sysctl: Fix data-races around ipv4_net_table (Round 6, Final). This series fixes data-races around 11 knobs after tcp_pacing_ss_ratio ipv4_net_table, and this is the final round for ipv4_net_table. While at it, other data-races around these related knobs are fixed. - decnet_mem - decnet_rmem - tipc_rmem There are still 58 tables possibly missing some fixes under net/. $ grep -rnE "struct ctl_table.*?\[\] =" net/ | wc -l 60 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 3e7d18b + 96b9bd8 commit 9af0620

File tree

10 files changed

+36
-31
lines changed

10 files changed

+36
-31
lines changed

include/net/sock.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2843,18 +2843,18 @@ static inline int sk_get_wmem0(const struct sock *sk, const struct proto *proto)
28432843
{
28442844
/* Does this proto have per netns sysctl_wmem ? */
28452845
if (proto->sysctl_wmem_offset)
2846-
return *(int *)((void *)sock_net(sk) + proto->sysctl_wmem_offset);
2846+
return READ_ONCE(*(int *)((void *)sock_net(sk) + proto->sysctl_wmem_offset));
28472847

2848-
return *proto->sysctl_wmem;
2848+
return READ_ONCE(*proto->sysctl_wmem);
28492849
}
28502850

28512851
static inline int sk_get_rmem0(const struct sock *sk, const struct proto *proto)
28522852
{
28532853
/* Does this proto have per netns sysctl_rmem ? */
28542854
if (proto->sysctl_rmem_offset)
2855-
return *(int *)((void *)sock_net(sk) + proto->sysctl_rmem_offset);
2855+
return READ_ONCE(*(int *)((void *)sock_net(sk) + proto->sysctl_rmem_offset));
28562856

2857-
return *proto->sysctl_rmem;
2857+
return READ_ONCE(*proto->sysctl_rmem);
28582858
}
28592859

28602860
/* Default TCP Small queue budget is ~1 ms of data (1sec >> 10)

net/decnet/af_decnet.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,8 @@ static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gf
480480
sk->sk_family = PF_DECnet;
481481
sk->sk_protocol = 0;
482482
sk->sk_allocation = gfp;
483-
sk->sk_sndbuf = sysctl_decnet_wmem[1];
484-
sk->sk_rcvbuf = sysctl_decnet_rmem[1];
483+
sk->sk_sndbuf = READ_ONCE(sysctl_decnet_wmem[1]);
484+
sk->sk_rcvbuf = READ_ONCE(sysctl_decnet_rmem[1]);
485485

486486
/* Initialization of DECnet Session Control Port */
487487
scp = DN_SK(sk);

net/ipv4/fib_trie.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,7 @@ fib_find_matching_alias(struct net *net, const struct fib_rt_info *fri)
10421042

10431043
void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri)
10441044
{
1045+
u8 fib_notify_on_flag_change;
10451046
struct fib_alias *fa_match;
10461047
struct sk_buff *skb;
10471048
int err;
@@ -1063,14 +1064,16 @@ void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri)
10631064
WRITE_ONCE(fa_match->offload, fri->offload);
10641065
WRITE_ONCE(fa_match->trap, fri->trap);
10651066

1067+
fib_notify_on_flag_change = READ_ONCE(net->ipv4.sysctl_fib_notify_on_flag_change);
1068+
10661069
/* 2 means send notifications only if offload_failed was changed. */
1067-
if (net->ipv4.sysctl_fib_notify_on_flag_change == 2 &&
1070+
if (fib_notify_on_flag_change == 2 &&
10681071
READ_ONCE(fa_match->offload_failed) == fri->offload_failed)
10691072
goto out;
10701073

10711074
WRITE_ONCE(fa_match->offload_failed, fri->offload_failed);
10721075

1073-
if (!net->ipv4.sysctl_fib_notify_on_flag_change)
1076+
if (!fib_notify_on_flag_change)
10741077
goto out;
10751078

10761079
skb = nlmsg_new(fib_nlmsg_size(fa_match->fa_info), GFP_ATOMIC);

net/ipv4/tcp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,8 @@ void tcp_init_sock(struct sock *sk)
452452

453453
icsk->icsk_sync_mss = tcp_sync_mss;
454454

455-
WRITE_ONCE(sk->sk_sndbuf, sock_net(sk)->ipv4.sysctl_tcp_wmem[1]);
456-
WRITE_ONCE(sk->sk_rcvbuf, sock_net(sk)->ipv4.sysctl_tcp_rmem[1]);
455+
WRITE_ONCE(sk->sk_sndbuf, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_wmem[1]));
456+
WRITE_ONCE(sk->sk_rcvbuf, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[1]));
457457

458458
sk_sockets_allocated_inc(sk);
459459
}
@@ -1724,7 +1724,7 @@ int tcp_set_rcvlowat(struct sock *sk, int val)
17241724
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK)
17251725
cap = sk->sk_rcvbuf >> 1;
17261726
else
1727-
cap = sock_net(sk)->ipv4.sysctl_tcp_rmem[2] >> 1;
1727+
cap = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]) >> 1;
17281728
val = min(val, cap);
17291729
WRITE_ONCE(sk->sk_rcvlowat, val ? : 1);
17301730

net/ipv4/tcp_input.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ static void tcp_sndbuf_expand(struct sock *sk)
426426

427427
if (sk->sk_sndbuf < sndmem)
428428
WRITE_ONCE(sk->sk_sndbuf,
429-
min(sndmem, sock_net(sk)->ipv4.sysctl_tcp_wmem[2]));
429+
min(sndmem, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_wmem[2])));
430430
}
431431

432432
/* 2. Tuning advertised window (window_clamp, rcv_ssthresh)
@@ -461,7 +461,7 @@ static int __tcp_grow_window(const struct sock *sk, const struct sk_buff *skb,
461461
struct tcp_sock *tp = tcp_sk(sk);
462462
/* Optimize this! */
463463
int truesize = tcp_win_from_space(sk, skbtruesize) >> 1;
464-
int window = tcp_win_from_space(sk, sock_net(sk)->ipv4.sysctl_tcp_rmem[2]) >> 1;
464+
int window = tcp_win_from_space(sk, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2])) >> 1;
465465

466466
while (tp->rcv_ssthresh <= window) {
467467
if (truesize <= skb->len)
@@ -574,16 +574,17 @@ static void tcp_clamp_window(struct sock *sk)
574574
struct tcp_sock *tp = tcp_sk(sk);
575575
struct inet_connection_sock *icsk = inet_csk(sk);
576576
struct net *net = sock_net(sk);
577+
int rmem2;
577578

578579
icsk->icsk_ack.quick = 0;
580+
rmem2 = READ_ONCE(net->ipv4.sysctl_tcp_rmem[2]);
579581

580-
if (sk->sk_rcvbuf < net->ipv4.sysctl_tcp_rmem[2] &&
582+
if (sk->sk_rcvbuf < rmem2 &&
581583
!(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
582584
!tcp_under_memory_pressure(sk) &&
583585
sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0)) {
584586
WRITE_ONCE(sk->sk_rcvbuf,
585-
min(atomic_read(&sk->sk_rmem_alloc),
586-
net->ipv4.sysctl_tcp_rmem[2]));
587+
min(atomic_read(&sk->sk_rmem_alloc), rmem2));
587588
}
588589
if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf)
589590
tp->rcv_ssthresh = min(tp->window_clamp, 2U * tp->advmss);
@@ -745,7 +746,7 @@ void tcp_rcv_space_adjust(struct sock *sk)
745746

746747
do_div(rcvwin, tp->advmss);
747748
rcvbuf = min_t(u64, rcvwin * rcvmem,
748-
sock_net(sk)->ipv4.sysctl_tcp_rmem[2]);
749+
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]));
749750
if (rcvbuf > sk->sk_rcvbuf) {
750751
WRITE_ONCE(sk->sk_rcvbuf, rcvbuf);
751752

@@ -910,9 +911,9 @@ static void tcp_update_pacing_rate(struct sock *sk)
910911
* end of slow start and should slow down.
911912
*/
912913
if (tcp_snd_cwnd(tp) < tp->snd_ssthresh / 2)
913-
rate *= sock_net(sk)->ipv4.sysctl_tcp_pacing_ss_ratio;
914+
rate *= READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_pacing_ss_ratio);
914915
else
915-
rate *= sock_net(sk)->ipv4.sysctl_tcp_pacing_ca_ratio;
916+
rate *= READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_pacing_ca_ratio);
916917

917918
rate *= max(tcp_snd_cwnd(tp), tp->packets_out);
918919

@@ -5520,7 +5521,7 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
55205521
}
55215522

55225523
if (!tcp_is_sack(tp) ||
5523-
tp->compressed_ack >= sock_net(sk)->ipv4.sysctl_tcp_comp_sack_nr)
5524+
tp->compressed_ack >= READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_comp_sack_nr))
55245525
goto send_now;
55255526

55265527
if (tp->compressed_ack_rcv_nxt != tp->rcv_nxt) {
@@ -5541,11 +5542,12 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
55415542
if (tp->srtt_us && tp->srtt_us < rtt)
55425543
rtt = tp->srtt_us;
55435544

5544-
delay = min_t(unsigned long, sock_net(sk)->ipv4.sysctl_tcp_comp_sack_delay_ns,
5545+
delay = min_t(unsigned long,
5546+
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_comp_sack_delay_ns),
55455547
rtt * (NSEC_PER_USEC >> 3)/20);
55465548
sock_hold(sk);
55475549
hrtimer_start_range_ns(&tp->compressed_ack_timer, ns_to_ktime(delay),
5548-
sock_net(sk)->ipv4.sysctl_tcp_comp_sack_slack_ns,
5550+
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_comp_sack_slack_ns),
55495551
HRTIMER_MODE_REL_PINNED_SOFT);
55505552
}
55515553

net/ipv4/tcp_ipv4.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
10061006
if (skb) {
10071007
__tcp_v4_send_check(skb, ireq->ir_loc_addr, ireq->ir_rmt_addr);
10081008

1009-
tos = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ?
1009+
tos = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reflect_tos) ?
10101010
(tcp_rsk(req)->syn_tos & ~INET_ECN_MASK) |
10111011
(inet_sk(sk)->tos & INET_ECN_MASK) :
10121012
inet_sk(sk)->tos;
@@ -1526,7 +1526,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
15261526
/* Set ToS of the new socket based upon the value of incoming SYN.
15271527
* ECT bits are set later in tcp_init_transfer().
15281528
*/
1529-
if (sock_net(sk)->ipv4.sysctl_tcp_reflect_tos)
1529+
if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reflect_tos))
15301530
newinet->tos = tcp_rsk(req)->syn_tos & ~INET_ECN_MASK;
15311531

15321532
if (!dst) {

net/ipv4/tcp_output.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ void tcp_select_initial_window(const struct sock *sk, int __space, __u32 mss,
238238
*rcv_wscale = 0;
239239
if (wscale_ok) {
240240
/* Set window scaling on max possible window */
241-
space = max_t(u32, space, sock_net(sk)->ipv4.sysctl_tcp_rmem[2]);
241+
space = max_t(u32, space, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]));
242242
space = max_t(u32, space, sysctl_rmem_max);
243243
space = min_t(u32, space, *window_clamp);
244244
*rcv_wscale = clamp_t(int, ilog2(space) - 15,

net/ipv6/tcp_ipv6.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
546546
if (np->repflow && ireq->pktopts)
547547
fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
548548

549-
tclass = sock_net(sk)->ipv4.sysctl_tcp_reflect_tos ?
549+
tclass = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reflect_tos) ?
550550
(tcp_rsk(req)->syn_tos & ~INET_ECN_MASK) |
551551
(np->tclass & INET_ECN_MASK) :
552552
np->tclass;
@@ -1314,7 +1314,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
13141314
/* Set ToS of the new socket based upon the value of incoming SYN.
13151315
* ECT bits are set later in tcp_init_transfer().
13161316
*/
1317-
if (sock_net(sk)->ipv4.sysctl_tcp_reflect_tos)
1317+
if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_reflect_tos))
13181318
newnp->tclass = tcp_rsk(req)->syn_tos & ~INET_ECN_MASK;
13191319

13201320
/* Clone native IPv6 options from listening socket (if any)

net/mptcp/protocol.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,7 +1926,7 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied)
19261926

19271927
do_div(rcvwin, advmss);
19281928
rcvbuf = min_t(u64, rcvwin * rcvmem,
1929-
sock_net(sk)->ipv4.sysctl_tcp_rmem[2]);
1929+
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]));
19301930

19311931
if (rcvbuf > sk->sk_rcvbuf) {
19321932
u32 window_clamp;
@@ -2669,8 +2669,8 @@ static int mptcp_init_sock(struct sock *sk)
26692669
mptcp_ca_reset(sk);
26702670

26712671
sk_sockets_allocated_inc(sk);
2672-
sk->sk_rcvbuf = sock_net(sk)->ipv4.sysctl_tcp_rmem[1];
2673-
sk->sk_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[1];
2672+
sk->sk_rcvbuf = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[1]);
2673+
sk->sk_sndbuf = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_wmem[1]);
26742674

26752675
return 0;
26762676
}

net/tipc/socket.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
517517
timer_setup(&sk->sk_timer, tipc_sk_timeout, 0);
518518
sk->sk_shutdown = 0;
519519
sk->sk_backlog_rcv = tipc_sk_backlog_rcv;
520-
sk->sk_rcvbuf = sysctl_tipc_rmem[1];
520+
sk->sk_rcvbuf = READ_ONCE(sysctl_tipc_rmem[1]);
521521
sk->sk_data_ready = tipc_data_ready;
522522
sk->sk_write_space = tipc_write_space;
523523
sk->sk_destruct = tipc_sock_destruct;

0 commit comments

Comments
 (0)