diff options
author | Eric Dumazet <edumazet@google.com> | 2023-09-21 22:28:14 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-10-01 20:09:54 +0200 |
commit | 2a4319cf3c83fc5d1997466196b99b3e14584e76 (patch) | |
tree | 6870bc59660ec6a0bf828db2758f69038578ee1a | |
parent | net: lockless SO_{TYPE|PROTOCOL|DOMAIN|ERROR } setsockopt() (diff) | |
download | linux-2a4319cf3c83fc5d1997466196b99b3e14584e76.tar.xz linux-2a4319cf3c83fc5d1997466196b99b3e14584e76.zip |
net: lockless implementation of SO_BUSY_POLL, SO_PREFER_BUSY_POLL, SO_BUSY_POLL_BUDGET
Setting sk->sk_ll_usec, sk_prefer_busy_poll and sk_busy_poll_budget
do not require the socket lock, readers are lockless anyway.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/sock.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index 4d20b74a93cb..408081549bd7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1140,6 +1140,26 @@ int sk_setsockopt(struct sock *sk, int level, int optname, case SO_DOMAIN: case SO_ERROR: return -ENOPROTOOPT; +#ifdef CONFIG_NET_RX_BUSY_POLL + case SO_BUSY_POLL: + if (val < 0) + return -EINVAL; + WRITE_ONCE(sk->sk_ll_usec, val); + return 0; + case SO_PREFER_BUSY_POLL: + if (valbool && !sockopt_capable(CAP_NET_ADMIN)) + return -EPERM; + WRITE_ONCE(sk->sk_prefer_busy_poll, valbool); + return 0; + case SO_BUSY_POLL_BUDGET: + if (val > READ_ONCE(sk->sk_busy_poll_budget) && + !sockopt_capable(CAP_NET_ADMIN)) + return -EPERM; + if (val < 0 || val > U16_MAX) + return -EINVAL; + WRITE_ONCE(sk->sk_busy_poll_budget, val); + return 0; +#endif } sockopt_lock_sock(sk); @@ -1402,30 +1422,6 @@ set_sndbuf: sock_valbool_flag(sk, SOCK_SELECT_ERR_QUEUE, valbool); break; -#ifdef CONFIG_NET_RX_BUSY_POLL - case SO_BUSY_POLL: - if (val < 0) - ret = -EINVAL; - else - WRITE_ONCE(sk->sk_ll_usec, val); - break; - case SO_PREFER_BUSY_POLL: - if (valbool && !sockopt_capable(CAP_NET_ADMIN)) - ret = -EPERM; - else - WRITE_ONCE(sk->sk_prefer_busy_poll, valbool); - break; - case SO_BUSY_POLL_BUDGET: - if (val > READ_ONCE(sk->sk_busy_poll_budget) && !sockopt_capable(CAP_NET_ADMIN)) { - ret = -EPERM; - } else { - if (val < 0 || val > U16_MAX) - ret = -EINVAL; - else - WRITE_ONCE(sk->sk_busy_poll_budget, val); - } - break; -#endif case SO_MAX_PACING_RATE: { |