sock: add SOCK_ZEROCOPY sockopt
authorWillem de Bruijn <willemb@google.com>
Thu, 3 Aug 2017 20:29:40 +0000 (16:29 -0400)
committerDavid S. Miller <davem@davemloft.net>
Fri, 4 Aug 2017 04:37:29 +0000 (21:37 -0700)
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:
arch/alpha/include/uapi/asm/socket.h
arch/frv/include/uapi/asm/socket.h
arch/ia64/include/uapi/asm/socket.h
arch/m32r/include/uapi/asm/socket.h
arch/mips/include/uapi/asm/socket.h
arch/mn10300/include/uapi/asm/socket.h
arch/parisc/include/uapi/asm/socket.h
arch/s390/include/uapi/asm/socket.h
arch/sparc/include/uapi/asm/socket.h
arch/xtensa/include/uapi/asm/socket.h
include/uapi/asm-generic/socket.h
net/core/skbuff.c
net/core/sock.c

index 7b285dd4fe05b3647b87879eea0785c6ebbe1947..c6133a045352828f24c970f3d37fd9831df86d67 100644 (file)
 
 #define SO_PEERGROUPS          59
 
+#define SO_ZEROCOPY            60
+
 #endif /* _UAPI_ASM_SOCKET_H */
index f1e3b20dce9fd98c869ee125c281b7123ab74b5c..9abf02d6855a6d28a3cb4ce8b263662be46e02ed 100644 (file)
 
 #define SO_PEERGROUPS          59
 
+#define SO_ZEROCOPY            60
+
 #endif /* _ASM_SOCKET_H */
 
index 5dd5c5d0d64224098a85491b80cf4e4fed3070e7..002eb85a6941e73d255a6d5f15dc99a6a6843746 100644 (file)
 
 #define SO_PEERGROUPS          59
 
+#define SO_ZEROCOPY            60
+
 #endif /* _ASM_IA64_SOCKET_H */
index f8f7b47e247f2d88314f72e7a2f8aead2e247ffb..e268e51a38d1db46a07cf5304d4eca099d360911 100644 (file)
 
 #define SO_PEERGROUPS          59
 
+#define SO_ZEROCOPY            60
+
 #endif /* _ASM_M32R_SOCKET_H */
index 882823bec153a69e91522757058d5edaeb4bc64a..6c755bc0797513179d3865bd780ea9bab8a199e5 100644 (file)
 
 #define SO_PEERGROUPS          59
 
+#define SO_ZEROCOPY            60
+
 #endif /* _UAPI_ASM_SOCKET_H */
index c710db354ff222d9aab0d2ee2a5fdd3b9f971284..ac82a3f26dbf9f71117cc49429e11a083f62990b 100644 (file)
 
 #define SO_PEERGROUPS          59
 
+#define SO_ZEROCOPY            60
+
 #endif /* _ASM_SOCKET_H */
index a0d4dc9f4eb2ff412e37f811087a768b921ac5b9..3b2bf7ae703b55bbd7e877a47b13dbf1cdccab28 100644 (file)
 
 #define SO_PEERGROUPS          0x4034
 
+#define SO_ZEROCOPY            0x4035
+
 #endif /* _UAPI_ASM_SOCKET_H */
index 52a63f4175cb8de14d9da9fb1c086f23e02e5aaf..a56916c835654b4eae4781758d13865994fcbaa4 100644 (file)
 
 #define SO_PEERGROUPS          59
 
+#define SO_ZEROCOPY            60
+
 #endif /* _ASM_SOCKET_H */
index 186fd8199f5487f7f2947c5649176d343064a611..b2f5c50d09474b8c5c20a5c153d0834f7196bc4a 100644 (file)
@@ -98,6 +98,8 @@
 
 #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
index 3eed2761c149845ad333e6d4e110b8ecd1b3458e..220059999e74005ce35f9cb2dd58ea148e8faa2f 100644 (file)
 
 #define SO_PEERGROUPS          59
 
+#define SO_ZEROCOPY            60
+
 #endif /* _XTENSA_SOCKET_H */
index 9861be8da65e09e7a66ee9d5a543067b677af59e..e47c9e4362216e96482bde07acb12c9db4703e58 100644 (file)
 
 #define SO_PEERGROUPS          59
 
+#define SO_ZEROCOPY            60
+
 #endif /* __ASM_GENERIC_SOCKET_H */
index 0603e44950dade35d8d0d09c2c06aa7309222438..29e34bc6a17ce913bdd0315258b3c1836b995386 100644 (file)
@@ -922,6 +922,9 @@ struct ubuf_info *sock_zerocopy_alloc(struct sock *sk, size_t size)
 
        WARN_ON_ONCE(!in_task());
 
+       if (!sock_flag(sk, SOCK_ZEROCOPY))
+               return NULL;
+
        skb = sock_omalloc(sk, 0, GFP_KERNEL);
        if (!skb)
                return NULL;
index e8b696858cadf5cf6ea81abbfbc4725f82987d66..9ea988d25b0a58aaa43622e8cedac7b6bf326ab1 100644 (file)
@@ -1055,6 +1055,20 @@ set_rcvbuf:
                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;
@@ -1383,6 +1397,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                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).