a few corrections for SOCK_SUPPORT_ZC
Subsystems (8)
cover a few corrections for SOCK_SUPPORT_ZC
There are several places/cases that got overlooked in regards to SOCK_SUPPORT_ZC. We're lacking the flag for IPv6 UDP sockets and accepted TCP sockets. We also should clear the flag when someone tries to hijack a socket by replacing the ->sk_prot callbacks.
Pavel Begunkov (3):
udp: advertise ipv6 udp support for msghdr::ubuf_info
net: remove SOCK_SUPPORT_ZC from sockmap net/ulp: remove SOCK_SUPPORT_ZC from tls sockets
Stefan Metzmacher (1):
net: also flag accepted sockets supporting msghdr originated zerocopy
include/net/sock.h | 7 +++++++ net/ipv4/af_inet.c | 2 ++ net/ipv4/tcp_bpf.c | 4 ++-- net/ipv4/tcp_ulp.c | 3 +++ net/ipv4/udp_bpf.c | 4 ++-- net/ipv6/udp.c | 1 + net/unix/unix_bpf.c | 8 ++++---- 7 files changed, 21 insertions(+), 8 deletions(-)
Signature · 1 line
2.38.0
PATCH 1/4 udp: advertise ipv6 udp support for msghdr::ubuf_info
Mark udp ipv6 as supporting msghdr::ubuf_info. In the original commit SOCK_SUPPORT_ZC was supposed to be set by a udp_init_sock() call from udp6_init_sock(), butd38afeec26ed4 ("tcp/udp: Call inet6_destroy_sock() in IPv6 ...") removed it and so ipv6 udp misses the flag.
--- net/ipv6/udp.c | 1 + 1 file changed, 1 insertion(+)
net/ipv6/udp.c +1 -0
@@ -66,6 +66,7 @@ int udpv6_init_sock(struct sock *sk) {skb_queue_head_init (&udp_sk (sk)->reader_queue); sk->sk_destruct = udpv6_destruct_sock; +set_bit (SOCK_SUPPORT_ZC , &sk->sk_socket->flags);return 0 ; }
Signature · 1 line
2.38.0
PATCH 2/4 net: remove SOCK_SUPPORT_ZC from sockmap
In reply to Pavel Begunkovsockmap replaces ->sk_prot with its own callbacks, we should remove SOCK_SUPPORT_ZC as the new proto doesn't support msghdr::ubuf_info.
--- include/net/sock.h | 7 +++++++ net/ipv4/tcp_bpf.c | 4 ++-- net/ipv4/udp_bpf.c | 4 ++-- net/unix/unix_bpf.c | 8 ++++---- 4 files changed, 15 insertions(+), 8 deletions(-)
include/net/sock.h +7 -0
@@ -1889,6 +1889,13 @@ void sock_kfree_s(struct sock *sk, void *mem, int size);void sock_kzfree_s (struct sock *sk,void *mem,int size);void sk_send_sigurg (struct sock *sk); +static inline void sock_replace_proto (struct sock *sk,struct proto *proto) +{ +if (sk->sk_socket) +clear_bit (SOCK_SUPPORT_ZC , &sk->sk_socket->flags); +WRITE_ONCE (sk->sk_prot, proto); +} +struct sockcm_cookie {u64 transmit_time;u32 mark;
net/ipv4/tcp_bpf.c +2 -2
@@ -607,7 +607,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) }else { sk->sk_write_space = psock->saved_write_space;/* Pairs with lockless read in sk_clone_lock() */ -WRITE_ONCE (sk->sk_prot, psock->sk_proto); +sock_replace_proto (sk, psock->sk_proto); }return 0 ; }
@@ -620,7 +620,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) }/* Pairs with lockless read in sk_clone_lock() */ -WRITE_ONCE (sk->sk_prot, &tcp_bpf_prots[family][config]); +sock_replace_proto (sk, &tcp_bpf_prots[family][config]);return 0 ; }EXPORT_SYMBOL_GPL (tcp_bpf_update_proto);
net/ipv4/udp_bpf.c +2 -2
@@ -141,14 +141,14 @@ int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)if (restore) { sk->sk_write_space = psock->saved_write_space; -WRITE_ONCE (sk->sk_prot, psock->sk_proto); +sock_replace_proto (sk, psock->sk_proto);return 0 ; }if (sk->sk_family ==AF_INET6 )udp_bpf_check_v6_needs_rebuild (psock->sk_proto); -WRITE_ONCE (sk->sk_prot, &udp_bpf_prots[family]); +sock_replace_proto (sk, &udp_bpf_prots[family]);return 0 ; }EXPORT_SYMBOL_GPL (udp_bpf_update_proto);
net/unix/unix_bpf.c +4 -4
@@ -145,12 +145,12 @@ int unix_dgram_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool reif (restore) { sk->sk_write_space = psock->saved_write_space; -WRITE_ONCE (sk->sk_prot, psock->sk_proto); +sock_replace_proto (sk, psock->sk_proto);return 0 ; }unix_dgram_bpf_check_needs_rebuild (psock->sk_proto); -WRITE_ONCE (sk->sk_prot, &unix_dgram_bpf_prot); +sock_replace_proto (sk, &unix_dgram_bpf_prot);return 0 ; }
@@ -158,12 +158,12 @@ int unix_stream_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool r {if (restore) { sk->sk_write_space = psock->saved_write_space; -WRITE_ONCE (sk->sk_prot, psock->sk_proto); +sock_replace_proto (sk, psock->sk_proto);return 0 ; }unix_stream_bpf_check_needs_rebuild (psock->sk_proto); -WRITE_ONCE (sk->sk_prot, &unix_stream_bpf_prot); +sock_replace_proto (sk, &unix_stream_bpf_prot);return 0 ; }
Signature · 1 line
2.38.0
PATCH 3/4 net/ulp: remove SOCK_SUPPORT_ZC from tls sockets
In reply to Pavel BegunkovRemove SOCK_SUPPORT_ZC when we're setting ulp as it might not support msghdr::ubuf_info, e.g. like TLS replacing ->sk_prot with a new set of handlers.
--- net/ipv4/tcp_ulp.c | 3 +++ 1 file changed, 3 insertions(+)
net/ipv4/tcp_ulp.c +3 -0
@@ -136,6 +136,9 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)if (icsk->icsk_ulp_ops) goto out_err; +if (sk->sk_socket) +clear_bit (SOCK_SUPPORT_ZC , &sk->sk_socket->flags); + err = ulp_ops->init (sk);if (err) goto out_err;
Signature · 1 line
2.38.0
PATCH 4/4 net: also flag accepted sockets supporting msghdr originated zerocopy
In reply to Pavel BegunkovFrom: Stefan Metzmacher <[email protected]>
Without this only the client initiated tcp sockets have SOCK_SUPPORT_ZC. The listening socket on the server also has it, but the accepted connections didn't, which meant IORING_OP_SEND[MSG]_ZC will always fails with -EOPNOTSUPP.
--- net/ipv4/af_inet.c | 2 ++ 1 file changed, 2 insertions(+)
net/ipv4/af_inet.c +2 -0
@@ -754,6 +754,8 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags, (TCPF_ESTABLISHED |TCPF_SYN_RECV | TCPF_CLOSE_WAIT | TCPF_CLOSE))); +if (test_bit (SOCK_SUPPORT_ZC , &sock->flags)) +set_bit (SOCK_SUPPORT_ZC , &newsock->flags);sock_graft (sk2, newsock); newsock->state =SS_CONNECTED ;
Signature · 1 line
2.38.0
This series was applied to netdev/net.git (master) by Jakub Kicinski <[email protected]>:
Hello:
This series was applied to netdev/net.git (master) by Jakub Kicinski <[email protected]>:
Quoted 11 lines · On Thu, 27 Oct 2022 00:25:55 +0100 you wrote:
There are several places/cases that got overlooked in regards to
SOCK_SUPPORT_ZC. We're lacking the flag for IPv6 UDP sockets and accepted TCP sockets. We also should clear the flag when someone tries to hijack a socket by replacing the ->sk_prot callbacks.Pavel Begunkov (3):
udp: advertise ipv6 udp support formsghdr::ubuf_info
net: removeSOCK_SUPPORT_ZCfrom sockmap net/ulp: removeSOCK_SUPPORT_ZCfrom tls sockets[...]
Here is the summary with links:
- [net,1/4] udp: advertise ipv6 udp support for msghdr::ubuf_info
https://git.kernel.org/netdev/net/c/8f279fb00bb2 - [net,2/4] net: remove SOCK_SUPPORT_ZC from sockmap https://git.kernel.org/netdev/net/c/fee9ac06647e - [net,3/4] net/ulp: remove SOCK_SUPPORT_ZC from tls sockets https://git.kernel.org/netdev/net/c/e276d62dcfde - [net,4/4] net: also flag accepted sockets supporting msghdr originated zerocopy https://git.kernel.org/netdev/net/c/71b7786ea478
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html