On 08/30/2018 10:09 AM, Björn Töpel wrote: > From: Björn Töpel <bjorn.to...@intel.com> > > Previously, the AF_XDP (XDP_DRV/XDP_SKB copy-mode) ingress logic did > not include XDP meta data in the data buffers copied out to the user > application. > > In this commit, we check if meta data is available, and if so, it is > prepended to the frame. > > Signed-off-by: Björn Töpel <bjorn.to...@intel.com> > --- > net/xdp/xsk.c | 37 ++++++++++++++++++++++++++++--------- > 1 file changed, 28 insertions(+), 9 deletions(-) > > diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c > index 4e937cd7c17d..817e4cee1540 100644 > --- a/net/xdp/xsk.c > +++ b/net/xdp/xsk.c > @@ -55,20 +55,30 @@ EXPORT_SYMBOL(xsk_umem_discard_addr); > > static int __xsk_rcv(struct xdp_sock *xs, struct xdp_buff *xdp, u32 len) > { > - void *buffer; > + void *to_buf, *from_buf; > + u32 metalen; > u64 addr; > int err; > > if (!xskq_peek_addr(xs->umem->fq, &addr) || > - len > xs->umem->chunk_size_nohr) { > + len > xs->umem->chunk_size_nohr - XDP_PACKET_HEADROOM) { > xs->rx_dropped++; > return -ENOSPC; > } > > addr += xs->umem->headroom; > > - buffer = xdp_umem_get_data(xs->umem, addr); > - memcpy(buffer, xdp->data, len); > + if (xdp_data_meta_unsupported(xdp)) {
Nit: Probably makes sense to wrap with unlikely() since we expect all drivers to implement this. > + from_buf = xdp->data; > + metalen = 0; > + } else { > + from_buf = xdp->data_meta; > + metalen = xdp->data - xdp->data_meta; > + } > + > + to_buf = xdp_umem_get_data(xs->umem, addr); > + memcpy(to_buf, from_buf, len + metalen); > + addr += metalen; > err = xskq_produce_batch_desc(xs->rx, addr, len); > if (!err) { > xskq_discard_addr(xs->umem->fq); > @@ -111,8 +121,8 @@ void xsk_flush(struct xdp_sock *xs) > > int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp) > { > - u32 len = xdp->data_end - xdp->data; > - void *buffer; > + u32 metalen, len = xdp->data_end - xdp->data; > + void *to_buf, *from_buf; > u64 addr; > int err; > > @@ -120,15 +130,24 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct > xdp_buff *xdp) > return -EINVAL; > > if (!xskq_peek_addr(xs->umem->fq, &addr) || > - len > xs->umem->chunk_size_nohr) { > + len > xs->umem->chunk_size_nohr - XDP_PACKET_HEADROOM) { > xs->rx_dropped++; > return -ENOSPC; > } > > addr += xs->umem->headroom; > > - buffer = xdp_umem_get_data(xs->umem, addr); > - memcpy(buffer, xdp->data, len); > + if (xdp_data_meta_unsupported(xdp)) { > + from_buf = xdp->data; > + metalen = 0; Note that this condition should be dead code. netif_receive_generic_xdp() sets xdp->data_meta to xdp->data, so all good here and above is never hit. > + } else { > + from_buf = xdp->data_meta; > + metalen = xdp->data - xdp->data_meta; > + } > + > + to_buf = xdp_umem_get_data(xs->umem, addr); > + memcpy(to_buf, from_buf, len + metalen); > + addr += metalen; > err = xskq_produce_batch_desc(xs->rx, addr, len); > if (!err) { > xskq_discard_addr(xs->umem->fq); >