bpf: net: Avoid do_tcp_getsockopt() taking sk lock when called from bpf
authorMartin KaFai Lau <martin.lau@kernel.org>
Fri, 2 Sep 2022 00:28:21 +0000 (17:28 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 3 Sep 2022 03:34:31 +0000 (20:34 -0700)
Similar to the earlier commit that changed sk_setsockopt() to
use sockopt_{lock,release}_sock() such that it can avoid taking
lock when called from bpf.  This patch also changes do_tcp_getsockopt()
to use sockopt_{lock,release}_sock() such that a latter patch can
make bpf_getsockopt(SOL_TCP) to reuse do_tcp_getsockopt().

Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20220902002821.2889765-1-kafai@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
net/ipv4/tcp.c

index 108c430..45c737e 100644 (file)
@@ -4265,30 +4265,30 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
                if (copy_from_sockptr(&len, optlen, sizeof(int)))
                        return -EFAULT;
 
-               lock_sock(sk);
+               sockopt_lock_sock(sk);
                if (tp->saved_syn) {
                        if (len < tcp_saved_syn_len(tp->saved_syn)) {
                                len = tcp_saved_syn_len(tp->saved_syn);
                                if (copy_to_sockptr(optlen, &len, sizeof(int))) {
-                                       release_sock(sk);
+                                       sockopt_release_sock(sk);
                                        return -EFAULT;
                                }
-                               release_sock(sk);
+                               sockopt_release_sock(sk);
                                return -EINVAL;
                        }
                        len = tcp_saved_syn_len(tp->saved_syn);
                        if (copy_to_sockptr(optlen, &len, sizeof(int))) {
-                               release_sock(sk);
+                               sockopt_release_sock(sk);
                                return -EFAULT;
                        }
                        if (copy_to_sockptr(optval, tp->saved_syn->data, len)) {
-                               release_sock(sk);
+                               sockopt_release_sock(sk);
                                return -EFAULT;
                        }
                        tcp_saved_syn_free(tp);
-                       release_sock(sk);
+                       sockopt_release_sock(sk);
                } else {
-                       release_sock(sk);
+                       sockopt_release_sock(sk);
                        len = 0;
                        if (copy_to_sockptr(optlen, &len, sizeof(int)))
                                return -EFAULT;
@@ -4321,11 +4321,11 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
                        return -EINVAL;
                if (zc.msg_flags &  ~(TCP_VALID_ZC_MSG_FLAGS))
                        return -EINVAL;
-               lock_sock(sk);
+               sockopt_lock_sock(sk);
                err = tcp_zerocopy_receive(sk, &zc, &tss);
                err = BPF_CGROUP_RUN_PROG_GETSOCKOPT_KERN(sk, level, optname,
                                                          &zc, &len, err);
-               release_sock(sk);
+               sockopt_release_sock(sk);
                if (len >= offsetofend(struct tcp_zerocopy_receive, msg_flags))
                        goto zerocopy_rcv_cmsg;
                switch (len) {