diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-08-22 15:59:00 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-08-22 15:59:00 -0700 |
| commit | 718d6e8669cb8cf4deda8b69950b8f8c62dbbcaa (patch) | |
| tree | 872d306c59671201e58538bb5d6e1404bb4c7cf6 /net/ipv4/tcp.c | |
| parent | 02614eee26fbdfd73b944769001cefeff6ed008c (diff) | |
| parent | 9217146fee49575dfe4ac9416587392fc31171f1 (diff) | |
Merge branch 'tcp-user_mss-and-tcp_maxseg-series'
Eric Dumazet says:
====================
tcp: user_mss and TCP_MAXSEG series
Annotate data-races around tp->rx_opt.user_mss and make
TCP_MAXSEG lockless.
====================
Link: https://patch.msgid.link/20250821141901.18839-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/ipv4/tcp.c')
| -rw-r--r-- | net/ipv4/tcp.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 71a956fbfc55..99232903b03c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3760,7 +3760,7 @@ int tcp_sock_set_maxseg(struct sock *sk, int val) if (val && (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW)) return -EINVAL; - tcp_sk(sk)->rx_opt.user_mss = val; + WRITE_ONCE(tcp_sk(sk)->rx_opt.user_mss, val); return 0; } @@ -3890,15 +3890,13 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, WRITE_ONCE(inet_csk(sk)->icsk_delack_max, delack_max); return 0; } + case TCP_MAXSEG: + return tcp_sock_set_maxseg(sk, val); } sockopt_lock_sock(sk); switch (optname) { - case TCP_MAXSEG: - err = tcp_sock_set_maxseg(sk, val); - break; - case TCP_NODELAY: __tcp_sock_set_nodelay(sk, val); break; @@ -4383,6 +4381,7 @@ int do_tcp_getsockopt(struct sock *sk, int level, struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); struct net *net = sock_net(sk); + int user_mss; int val, len; if (copy_from_sockptr(&len, optlen, sizeof(int))) @@ -4396,9 +4395,10 @@ int do_tcp_getsockopt(struct sock *sk, int level, switch (optname) { case TCP_MAXSEG: val = tp->mss_cache; - if (tp->rx_opt.user_mss && + user_mss = READ_ONCE(tp->rx_opt.user_mss); + if (user_mss && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) - val = tp->rx_opt.user_mss; + val = user_mss; if (tp->repair) val = tp->rx_opt.mss_clamp; break; |
