diff mbox series

[bpf-next,04/14] bpf: net: Avoid do_tcp_setsockopt() taking sk lock when called from bpf

Message ID 20220727060921.2373314-1-kafai@fb.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series bpf: net: Remove duplicated codes from bpf_setsockopt() | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR fail PR summary
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 2 this patch: 2
netdev/cc_maintainers warning 2 maintainers not CCed: dsahern@kernel.org yoshfuji@linux-ipv6.org
netdev/build_clang success Errors and warnings before: 5 this patch: 5
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 2 this patch: 2
netdev/checkpatch warning WARNING: line length of 83 exceeds 80 columns WARNING: line length of 89 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-1 success Logs for Kernel LATEST on ubuntu-latest with gcc
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Kernel LATEST on ubuntu-latest with llvm-15
bpf/vmtest-bpf-next-VM_Test-3 fail Logs for Kernel LATEST on z15 with gcc

Commit Message

Martin KaFai Lau July 27, 2022, 6:09 a.m. UTC
Similar to the earlier patch that avoids sock_setsockopt() from
taking sk lock when called from bpf.  This patch changes
do_tcp_setsockopt() to use the {lock,release}_sock_sockopt().

This patch also changes do_tcp_setsockopt() to check optval.is_bpf
when passing the cap_net_admin arg to
tcp_set_congestion_control(..., cap_net_admin).  It is
the same as how bpf_setsockopt(TCP_CONGESTION) is calling
tcp_set_congestion_control() now.

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
---
 net/ipv4/tcp.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index ba2bdc811374..7f8d81befa8e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3462,11 +3462,12 @@  static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
 			return -EFAULT;
 		name[val] = 0;
 
-		lock_sock(sk);
-		err = tcp_set_congestion_control(sk, name, true,
-						 ns_capable(sock_net(sk)->user_ns,
-							    CAP_NET_ADMIN));
-		release_sock(sk);
+		lock_sock_sockopt(sk, optval);
+		err = tcp_set_congestion_control(sk, name, !optval.is_bpf,
+						 optval.is_bpf ?
+						 true : ns_capable(sock_net(sk)->user_ns,
+								   CAP_NET_ADMIN));
+		release_sock_sockopt(sk, optval);
 		return err;
 	}
 	case TCP_ULP: {
@@ -3482,9 +3483,9 @@  static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
 			return -EFAULT;
 		name[val] = 0;
 
-		lock_sock(sk);
+		lock_sock_sockopt(sk, optval);
 		err = tcp_set_ulp(sk, name);
-		release_sock(sk);
+		release_sock_sockopt(sk, optval);
 		return err;
 	}
 	case TCP_FASTOPEN_KEY: {
@@ -3517,7 +3518,7 @@  static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
 	if (copy_from_sockptr(&val, optval, sizeof(val)))
 		return -EFAULT;
 
-	lock_sock(sk);
+	lock_sock_sockopt(sk, optval);
 
 	switch (optname) {
 	case TCP_MAXSEG:
@@ -3739,7 +3740,7 @@  static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
 		break;
 	}
 
-	release_sock(sk);
+	release_sock_sockopt(sk, optval);
 	return err;
 }