On Sat, Jun 29, 2019 at 08:23:25AM +0300, Ilias Apalodimas wrote:
The interface only supports 1 Tx queue so locking is introduced on
the Tx queue if XDP is enabled to make sure .ndo_start_xmit and
.ndo_xdp_xmit won't corrupt Tx ring

- Performance (SMMU off)

Benchmark   XDP_SKB     XDP_DRV
xdp1        291kpps     344kpps
rxdrop      282kpps     342kpps

- Performance (SMMU on)
Benchmark   XDP_SKB     XDP_DRV
xdp1        167kpps     324kpps
rxdrop      164kpps     323kpps

Signed-off-by: Ilias Apalodimas <ilias.apalodi...@linaro.org>
---
drivers/net/ethernet/socionext/netsec.c | 361 ++++++++++++++++++++++--
1 file changed, 334 insertions(+), 27 deletions(-)


[...]

+
+static int netsec_xdp_setup(struct netsec_priv *priv, struct bpf_prog *prog,
+                           struct netlink_ext_ack *extack)
+{
+       struct net_device *dev = priv->ndev;
+       struct bpf_prog *old_prog;
+
+       /* For now just support only the usual MTU sized frames */
+       if (prog && dev->mtu > 1500) {
+               NL_SET_ERR_MSG_MOD(extack, "Jumbo frames not supported on XDP");
+               return -EOPNOTSUPP;
+       }
+
+       if (netif_running(dev))
+               netsec_netdev_stop(dev);
And why to stop the interface. XDP allows to update prog in runtime.

+
+       /* Detach old prog, if any */
+       old_prog = xchg(&priv->xdp_prog, prog);
+       if (old_prog)
+               bpf_prog_put(old_prog);
+
+       if (netif_running(dev))
+               netsec_netdev_open(dev);
+
+       return 0;
+}
+
+static int netsec_xdp(struct net_device *ndev, struct netdev_bpf *xdp)
+{
+       struct netsec_priv *priv = netdev_priv(ndev);
+
+       switch (xdp->command) {
+       case XDP_SETUP_PROG:
+               return netsec_xdp_setup(priv, xdp->prog, xdp->extack);
+       case XDP_QUERY_PROG:
+               xdp->prog_id = priv->xdp_prog ? priv->xdp_prog->aux->id : 0;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
static const struct net_device_ops netsec_netdev_ops = {
        .ndo_init               = netsec_netdev_init,
        .ndo_uninit             = netsec_netdev_uninit,
@@ -1537,6 +1842,8 @@ static const struct net_device_ops netsec_netdev_ops = {
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = netsec_netdev_ioctl,
+       .ndo_xdp_xmit           = netsec_xdp_xmit,
+       .ndo_bpf                = netsec_xdp,
};

static int netsec_of_probe(struct platform_device *pdev,
--
2.20.1


--
Regards,
Ivan Khoronzhuk

Reply via email to