i40e: implement flush flag for ndo_xdp_xmit
authorJesper Dangaard Brouer <brouer@redhat.com>
Thu, 31 May 2018 08:59:52 +0000 (10:59 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Sun, 3 Jun 2018 15:11:34 +0000 (08:11 -0700)
When passed the XDP_XMIT_FLUSH flag i40e_xdp_xmit now performs the
same kind of ring tail update as in i40e_xdp_flush.  The advantage is
that all the necessary checks have been performed and xdp_ring can be
updated, instead of having to perform the exact same steps/checks in
i40e_xdp_flush

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
drivers/net/ethernet/intel/i40e/i40e_txrx.c

index c0451d6..5f01e4c 100644 (file)
@@ -3676,6 +3676,7 @@ int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
        struct i40e_netdev_priv *np = netdev_priv(dev);
        unsigned int queue_index = smp_processor_id();
        struct i40e_vsi *vsi = np->vsi;
+       struct i40e_ring *xdp_ring;
        int drops = 0;
        int i;
 
@@ -3685,20 +3686,25 @@ int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
        if (!i40e_enabled_xdp_vsi(vsi) || queue_index >= vsi->num_queue_pairs)
                return -ENXIO;
 
-       if (unlikely(flags & ~XDP_XMIT_FLAGS_NONE))
+       if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
                return -EINVAL;
 
+       xdp_ring = vsi->xdp_rings[queue_index];
+
        for (i = 0; i < n; i++) {
                struct xdp_frame *xdpf = frames[i];
                int err;
 
-               err = i40e_xmit_xdp_ring(xdpf, vsi->xdp_rings[queue_index]);
+               err = i40e_xmit_xdp_ring(xdpf, xdp_ring);
                if (err != I40E_XDP_TX) {
                        xdp_return_frame_rx_napi(xdpf);
                        drops++;
                }
        }
 
+       if (unlikely(flags & XDP_XMIT_FLUSH))
+               i40e_xdp_ring_update_tail(xdp_ring);
+
        return n - drops;
 }