summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2023-09-21 22:28:14 +0200
committerDavid S. Miller <davem@davemloft.net>2023-10-01 20:09:54 +0200
commit2a4319cf3c83fc5d1997466196b99b3e14584e76 (patch)
tree6870bc59660ec6a0bf828db2758f69038578ee1a
parentnet: lockless SO_{TYPE|PROTOCOL|DOMAIN|ERROR } setsockopt() (diff)
downloadlinux-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.c44
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:
{