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:
Willem de Bruijn
2017-08-03 16:29:40 -04:00
committad av David S. Miller
förälder 52267790ef
incheckning 76851d1212
13 ändrade filer med 43 tillägg och 0 borttagningar

Visa fil

@@ -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;

Visa fil

@@ -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).