diff options
author | Eric Dumazet <edumazet@google.com> | 2023-08-04 14:46:12 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-08-06 08:24:55 +0100 |
commit | d58f2e15aa0c07f6f03ec71f64d7697ca43d04a1 (patch) | |
tree | 3960ed5a1992d8493345910ebabf2ad770fa7a4b /net/ipv4/tcp.c | |
parent | d44fd4a767b3755899f8ad1df3e8eca3961ba708 (diff) |
tcp: set TCP_USER_TIMEOUT locklessly
icsk->icsk_user_timeout can be set locklessly,
if all read sides use READ_ONCE().
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index bcbb33a8c152..34c2a40b0247 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3296,11 +3296,16 @@ int tcp_sock_set_syncnt(struct sock *sk, int val) } EXPORT_SYMBOL(tcp_sock_set_syncnt); -void tcp_sock_set_user_timeout(struct sock *sk, u32 val) +int tcp_sock_set_user_timeout(struct sock *sk, int val) { - lock_sock(sk); + /* Cap the max time in ms TCP will retry or probe the window + * before giving up and aborting (ETIMEDOUT) a connection. + */ + if (val < 0) + return -EINVAL; + WRITE_ONCE(inet_csk(sk)->icsk_user_timeout, val); - release_sock(sk); + return 0; } EXPORT_SYMBOL(tcp_sock_set_user_timeout); @@ -3464,6 +3469,8 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, switch (optname) { case TCP_SYNCNT: return tcp_sock_set_syncnt(sk, val); + case TCP_USER_TIMEOUT: + return tcp_sock_set_user_timeout(sk, val); } sockopt_lock_sock(sk); @@ -3611,16 +3618,6 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, err = tp->af_specific->md5_parse(sk, optname, optval, optlen); break; #endif - case TCP_USER_TIMEOUT: - /* Cap the max time in ms TCP will retry or probe the window - * before giving up and aborting (ETIMEDOUT) a connection. - */ - if (val < 0) - err = -EINVAL; - else - WRITE_ONCE(icsk->icsk_user_timeout, val); - break; - case TCP_FASTOPEN: if (val >= 0 && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { |