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>
13 files changed:
+#define SO_ZEROCOPY 60
+
#endif /* _UAPI_ASM_SOCKET_H */
#endif /* _UAPI_ASM_SOCKET_H */
+#define SO_ZEROCOPY 60
+
#endif /* _ASM_SOCKET_H */
#endif /* _ASM_SOCKET_H */
+#define SO_ZEROCOPY 60
+
#endif /* _ASM_IA64_SOCKET_H */
#endif /* _ASM_IA64_SOCKET_H */
+#define SO_ZEROCOPY 60
+
#endif /* _ASM_M32R_SOCKET_H */
#endif /* _ASM_M32R_SOCKET_H */
+#define SO_ZEROCOPY 60
+
#endif /* _UAPI_ASM_SOCKET_H */
#endif /* _UAPI_ASM_SOCKET_H */
+#define SO_ZEROCOPY 60
+
#endif /* _ASM_SOCKET_H */
#endif /* _ASM_SOCKET_H */
#define SO_PEERGROUPS 0x4034
#define SO_PEERGROUPS 0x4034
+#define SO_ZEROCOPY 0x4035
+
#endif /* _UAPI_ASM_SOCKET_H */
#endif /* _UAPI_ASM_SOCKET_H */
+#define SO_ZEROCOPY 60
+
#endif /* _ASM_SOCKET_H */
#endif /* _ASM_SOCKET_H */
#define SO_PEERGROUPS 0x003d
#define SO_PEERGROUPS 0x003d
+#define SO_ZEROCOPY 0x003e
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
+#define SO_ZEROCOPY 60
+
#endif /* _XTENSA_SOCKET_H */
#endif /* _XTENSA_SOCKET_H */
+#define SO_ZEROCOPY 60
+
#endif /* __ASM_GENERIC_SOCKET_H */
#endif /* __ASM_GENERIC_SOCKET_H */
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);
if (!skb)
return NULL;
skb = sock_omalloc(sk, 0, GFP_KERNEL);
if (!skb)
return NULL;
if (val == 1)
dst_negative_advice(sk);
break;
if (val == 1)
dst_negative_advice(sk);
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:
ret = -ENOPROTOOPT;
break;
default:
ret = -ENOPROTOOPT;
break;
v.val64 = sock_gen_cookie(sk);
break;
v.val64 = sock_gen_cookie(sk);
break;
+ case SO_ZEROCOPY:
+ v.val = sock_flag(sk, SOCK_ZEROCOPY);
+ break;
+
default:
/* We implement the SO_SNDLOWAT etc to not be settable
* (1003.1g 7).
default:
/* We implement the SO_SNDLOWAT etc to not be settable
* (1003.1g 7).