]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ixgbe: respect metadata on XSK Rx to skb
authorAlexander Lobakin <alexandr.lobakin@intel.com>
Wed, 8 Dec 2021 14:07:02 +0000 (15:07 +0100)
committerStefan Bader <stefan.bader@canonical.com>
Fri, 20 May 2022 12:38:44 +0000 (14:38 +0200)
BugLink: https://bugs.launchpad.net/bugs/1969110
[ Upstream commit f322a620be69e95594eda89502b478aa7dbf6ec2 ]

For now, if the XDP prog returns XDP_PASS on XSK, the metadata
will be lost as it doesn't get copied to the skb.

Copy it along with the frame headers. Account its size on skb
allocation, and when copying just treat it as a part of the frame
and do a pull after to "move" it to the "reserved" zone.

net_prefetch() xdp->data_meta and align the copy size to speed-up
memcpy() a little and better match ixgbe_construct_skb().

Fixes: d0bcacd0a130 ("ixgbe: add AF_XDP zero-copy Rx support")
Suggested-by: Jesper Dangaard Brouer <brouer@redhat.com>
Suggested-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com>
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
(cherry picked from commit cb42b6cfc5b09cf3f6f963435732d5f3b552a050)
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c

index 36f43dc3a55e6bc1cd7b019b621a478bc0255344..b399b9c147172dfc6db8926e222f2b3d926c57f4 100644 (file)
@@ -203,19 +203,25 @@ bool ixgbe_alloc_rx_buffers_zc(struct ixgbe_ring *rx_ring, u16 count)
 static struct sk_buff *ixgbe_construct_skb_zc(struct ixgbe_ring *rx_ring,
                                              const struct xdp_buff *xdp)
 {
+       unsigned int totalsize = xdp->data_end - xdp->data_meta;
        unsigned int metasize = xdp->data - xdp->data_meta;
-       unsigned int datasize = xdp->data_end - xdp->data;
        struct sk_buff *skb;
 
+       net_prefetch(xdp->data_meta);
+
        /* allocate a skb to store the frags */
-       skb = __napi_alloc_skb(&rx_ring->q_vector->napi, datasize,
+       skb = __napi_alloc_skb(&rx_ring->q_vector->napi, totalsize,
                               GFP_ATOMIC | __GFP_NOWARN);
        if (unlikely(!skb))
                return NULL;
 
-       memcpy(__skb_put(skb, datasize), xdp->data, datasize);
-       if (metasize)
+       memcpy(__skb_put(skb, totalsize), xdp->data_meta,
+              ALIGN(totalsize, sizeof(long)));
+
+       if (metasize) {
                skb_metadata_set(skb, metasize);
+               __skb_pull(skb, metasize);
+       }
 
        return skb;
 }