Willem de Bruijn <willemdebruijn.kernel@xxxxxxxxx> wrote: > > + } else if ((flags & MSG_SPLICE_PAGES) && length) { > > + if (inet->hdrincl) > > + return -EPERM; > > + if (rt->dst.dev->features & NETIF_F_SG) > > + /* We need an empty buffer to attach stuff to */ > > + initial_length = transhdrlen; > > I still don't entirely understand what initial_length means. > > More importantly, transhdrlen can be zero. If not called for UDP > but for RAW. Or if this is a subsequent call to a packet that is > being held with MSG_MORE. > > This works fine for existing use-cases, which go to alloc_new_skb. > Not sure how this case would be different. But the comment alludes > that it does. The problem is that in the non-MSG_ZEROCOPY case, __ip_append_data() assumes that it's going to copy the data it is given and will allocate sufficient space in the skb in advance to hold it - but I don't want to do that because I want to splice in the pages holding the data instead. However, I do need to allocate space to hold the transport header. Maybe I should change 'initial_length' to 'initial_alloc'? It represents the amount I think we should allocate. Or maybe I should have a separate allocation clause for MSG_SPLICE_PAGES? I also wonder if __ip_append_data() really needs two places that call getfrag(). David