zerocopy udp ---------- Forwarded message --------- From: Pavel Begunkov <asml.sile...@gmail.com> Date: Tue, Dec 21, 2021 at 11:16 PM Subject: [RFC v2 07/19] ipv6/udp: add support msgdr::msg_ubuf To: <io-ur...@vger.kernel.org>, <net...@vger.kernel.org>, <linux-ker...@vger.kernel.org> Cc: Jakub Kicinski <k...@kernel.org>, Jonathan Lemon <jonathan.le...@gmail.com>, David S . Miller <da...@davemloft.net>, Willem de Bruijn <will...@google.com>, Eric Dumazet <eduma...@google.com>, David Ahern <dsah...@kernel.org>, Jens Axboe <ax...@kernel.dk>, Pavel Begunkov <asml.sile...@gmail.com>
Make ipv6/udp to use ubuf_info passed in struct msghdr if it was specified. Signed-off-by: Pavel Begunkov <asml.sile...@gmail.com> --- net/ipv6/ip6_output.c | 49 ++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 2f044a49afa8..822e3894dd3b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1452,6 +1452,7 @@ static int __ip6_append_data(struct sock *sk, unsigned int maxnonfragsize, headersize; unsigned int wmem_alloc_delta = 0; bool paged, extra_uref = false; + bool zc = false; skb = skb_peek_tail(queue); if (!skb) { @@ -1516,17 +1517,37 @@ static int __ip6_append_data(struct sock *sk, rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) csummode = CHECKSUM_PARTIAL; - if (flags & MSG_ZEROCOPY && length && sock_flag(sk, SOCK_ZEROCOPY)) { - uarg = msg_zerocopy_realloc(sk, length, skb_zcopy(skb)); - if (!uarg) - return -ENOBUFS; - extra_uref = !skb_zcopy(skb); /* only ref on new uarg */ - if (rt->dst.dev->features & NETIF_F_SG && - csummode == CHECKSUM_PARTIAL) { - paged = true; - } else { - uarg->zerocopy = 0; - skb_zcopy_set(skb, uarg, &extra_uref); + if ((flags & MSG_ZEROCOPY) && length) { + struct msghdr *msg = from; + + if (getfrag == ip_generic_getfrag && msg->msg_ubuf) { + uarg = msg->msg_ubuf; + if (skb_zcopy(skb) && uarg != skb_zcopy(skb)) + return -EINVAL; + + if (rt->dst.dev->features & NETIF_F_SG && + csummode == CHECKSUM_PARTIAL) { + paged = true; + zc = true; + } else { + /* Drop uarg if can't zerocopy, callers should + * be able to handle it. + */ + uarg = NULL; + } + } else if (sock_flag(sk, SOCK_ZEROCOPY)) { + uarg = msg_zerocopy_realloc(sk, length, skb_zcopy(skb)); + if (!uarg) + return -ENOBUFS; + extra_uref = !skb_zcopy(skb); /* only ref on new uarg */ + if (rt->dst.dev->features & NETIF_F_SG && + csummode == CHECKSUM_PARTIAL) { + paged = true; + zc = true; + } else { + uarg->zerocopy = 0; + skb_zcopy_set(skb, uarg, &extra_uref); + } } } @@ -1717,9 +1738,13 @@ static int __ip6_append_data(struct sock *sk, err = -EFAULT; goto error; } - } else if (!uarg || !uarg->zerocopy) { + } else if (!zc) { int i = skb_shinfo(skb)->nr_frags; + if (skb_shinfo(skb)->flags & SKBFL_MANAGED_FRAGS) { + err = -EFAULT; + goto error; + } err = -ENOMEM; if (!sk_page_frag_refill(sk, pfrag)) goto error; -- 2.34.1 -- I tried to build a better future, a few times: https://wayforward.archive.org/?site=https%3A%2F%2Fwww.icei.org Dave Täht CEO, TekLibre, LLC _______________________________________________ Cerowrt-devel mailing list Cerowrt-devel@lists.bufferbloat.net https://lists.bufferbloat.net/listinfo/cerowrt-devel