bpf: net: Avoid do_ip_getsockopt() taking sk lock when called from bpf
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_ip_getsockopt() to use sockopt_{lock,release}_sock() such that a latter patch can make bpf_getsockopt(SOL_IP) to reuse do_ip_getsockopt(). Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Link: https://lore.kernel.org/r/20220902002834.2891514-1-kafai@fb.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Родитель
728f064cd7
Коммит
1985320c54
|
@ -1545,7 +1545,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||
|
||||
if (needs_rtnl)
|
||||
rtnl_lock();
|
||||
lock_sock(sk);
|
||||
sockopt_lock_sock(sk);
|
||||
|
||||
switch (optname) {
|
||||
case IP_OPTIONS:
|
||||
|
@ -1561,7 +1561,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||
memcpy(optbuf, &inet_opt->opt,
|
||||
sizeof(struct ip_options) +
|
||||
inet_opt->opt.optlen);
|
||||
release_sock(sk);
|
||||
sockopt_release_sock(sk);
|
||||
|
||||
if (opt->optlen == 0) {
|
||||
len = 0;
|
||||
|
@ -1637,7 +1637,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||
dst_release(dst);
|
||||
}
|
||||
if (!val) {
|
||||
release_sock(sk);
|
||||
sockopt_release_sock(sk);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
break;
|
||||
|
@ -1662,7 +1662,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||
struct in_addr addr;
|
||||
len = min_t(unsigned int, len, sizeof(struct in_addr));
|
||||
addr.s_addr = inet->mc_addr;
|
||||
release_sock(sk);
|
||||
sockopt_release_sock(sk);
|
||||
|
||||
if (copy_to_sockptr(optlen, &len, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
@ -1699,7 +1699,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||
{
|
||||
struct msghdr msg;
|
||||
|
||||
release_sock(sk);
|
||||
sockopt_release_sock(sk);
|
||||
|
||||
if (sk->sk_type != SOCK_STREAM)
|
||||
return -ENOPROTOOPT;
|
||||
|
@ -1743,10 +1743,10 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||
val = inet->min_ttl;
|
||||
break;
|
||||
default:
|
||||
release_sock(sk);
|
||||
sockopt_release_sock(sk);
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
release_sock(sk);
|
||||
sockopt_release_sock(sk);
|
||||
|
||||
if (len < sizeof(int) && len > 0 && val >= 0 && val <= 255) {
|
||||
unsigned char ucval = (unsigned char)val;
|
||||
|
@ -1765,7 +1765,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|||
return 0;
|
||||
|
||||
out:
|
||||
release_sock(sk);
|
||||
sockopt_release_sock(sk);
|
||||
if (needs_rtnl)
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
|
|
Загрузка…
Ссылка в новой задаче