sock: add SOCK_ZEROCOPY sockopt
The send call ignores unknown flags. Legacy applications may already unwittingly pass MSG_ZEROCOPY. Continue to ignore this flag unless a socket opts in to zerocopy. Introduce socket option SO_ZEROCOPY to enable MSG_ZEROCOPY processing. Processes can also query this socket option to detect kernel support for the feature. Older kernels will return ENOPROTOOPT. Signed-off-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
52267790ef
commit
76851d1212
@ -109,4 +109,6 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 59
|
#define SO_PEERGROUPS 59
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 60
|
||||||
|
|
||||||
#endif /* _UAPI_ASM_SOCKET_H */
|
#endif /* _UAPI_ASM_SOCKET_H */
|
||||||
|
@ -102,5 +102,7 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 59
|
#define SO_PEERGROUPS 59
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 60
|
||||||
|
|
||||||
#endif /* _ASM_SOCKET_H */
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
|
||||||
|
@ -111,4 +111,6 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 59
|
#define SO_PEERGROUPS 59
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 60
|
||||||
|
|
||||||
#endif /* _ASM_IA64_SOCKET_H */
|
#endif /* _ASM_IA64_SOCKET_H */
|
||||||
|
@ -102,4 +102,6 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 59
|
#define SO_PEERGROUPS 59
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 60
|
||||||
|
|
||||||
#endif /* _ASM_M32R_SOCKET_H */
|
#endif /* _ASM_M32R_SOCKET_H */
|
||||||
|
@ -120,4 +120,6 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 59
|
#define SO_PEERGROUPS 59
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 60
|
||||||
|
|
||||||
#endif /* _UAPI_ASM_SOCKET_H */
|
#endif /* _UAPI_ASM_SOCKET_H */
|
||||||
|
@ -102,4 +102,6 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 59
|
#define SO_PEERGROUPS 59
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 60
|
||||||
|
|
||||||
#endif /* _ASM_SOCKET_H */
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
@ -101,4 +101,6 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 0x4034
|
#define SO_PEERGROUPS 0x4034
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 0x4035
|
||||||
|
|
||||||
#endif /* _UAPI_ASM_SOCKET_H */
|
#endif /* _UAPI_ASM_SOCKET_H */
|
||||||
|
@ -108,4 +108,6 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 59
|
#define SO_PEERGROUPS 59
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 60
|
||||||
|
|
||||||
#endif /* _ASM_SOCKET_H */
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
@ -98,6 +98,8 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 0x003d
|
#define SO_PEERGROUPS 0x003d
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 0x003e
|
||||||
|
|
||||||
/* Security levels - as per NRL IPv6 - don't actually do anything */
|
/* Security levels - as per NRL IPv6 - don't actually do anything */
|
||||||
#define SO_SECURITY_AUTHENTICATION 0x5001
|
#define SO_SECURITY_AUTHENTICATION 0x5001
|
||||||
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
|
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
|
||||||
|
@ -113,4 +113,6 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 59
|
#define SO_PEERGROUPS 59
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 60
|
||||||
|
|
||||||
#endif /* _XTENSA_SOCKET_H */
|
#endif /* _XTENSA_SOCKET_H */
|
||||||
|
@ -104,4 +104,6 @@
|
|||||||
|
|
||||||
#define SO_PEERGROUPS 59
|
#define SO_PEERGROUPS 59
|
||||||
|
|
||||||
|
#define SO_ZEROCOPY 60
|
||||||
|
|
||||||
#endif /* __ASM_GENERIC_SOCKET_H */
|
#endif /* __ASM_GENERIC_SOCKET_H */
|
||||||
|
@ -922,6 +922,9 @@ struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size)
|
|||||||
|
|
||||||
WARN_ON_ONCE(!in_task());
|
WARN_ON_ONCE(!in_task());
|
||||||
|
|
||||||
|
if (!sock_flag(sk, SOCK_ZEROCOPY))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
skb = sock_omalloc(sk, 0, GFP_KERNEL);
|
skb = sock_omalloc(sk, 0, GFP_KERNEL);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1055,6 +1055,20 @@ set_rcvbuf:
|
|||||||
if (val == 1)
|
if (val == 1)
|
||||||
dst_negative_advice(sk);
|
dst_negative_advice(sk);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SO_ZEROCOPY:
|
||||||
|
if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
|
||||||
|
ret = -ENOTSUPP;
|
||||||
|
else if (sk->sk_protocol != IPPROTO_TCP)
|
||||||
|
ret = -ENOTSUPP;
|
||||||
|
else if (sk->sk_state != TCP_CLOSE)
|
||||||
|
ret = -EBUSY;
|
||||||
|
else if (val < 0 || val > 1)
|
||||||
|
ret = -EINVAL;
|
||||||
|
else
|
||||||
|
sock_valbool_flag(sk, SOCK_ZEROCOPY, valbool);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = -ENOPROTOOPT;
|
ret = -ENOPROTOOPT;
|
||||||
break;
|
break;
|
||||||
@ -1383,6 +1397,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
|||||||
v.val64 = sock_gen_cookie(sk);
|
v.val64 = sock_gen_cookie(sk);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SO_ZEROCOPY:
|
||||||
|
v.val = sock_flag(sk, SOCK_ZEROCOPY);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* We implement the SO_SNDLOWAT etc to not be settable
|
/* We implement the SO_SNDLOWAT etc to not be settable
|
||||||
* (1003.1g 7).
|
* (1003.1g 7).
|
||||||
|
Loading…
Reference in New Issue
Block a user