RE: [PATCH net-next 1/8] dpaa2-eth: Add basic XDP support

2018-11-26 Thread Camelia Alexandra Groza
> -Original Message-
> From: netdev-ow...@vger.kernel.org 
> On Behalf Of Ioana Ciocoi Radulescu
> Sent: Friday, November 23, 2018 18:57
> To: netdev@vger.kernel.org; da...@davemloft.net
> Subject: [PATCH net-next 1/8] dpaa2-eth: Add basic XDP support
> 
> +static int dpaa2_eth_change_mtu(struct net_device *dev, int new_mtu)
> +{
> + struct dpaa2_eth_priv *priv = netdev_priv(dev);
> + int err;
> +
> + if (!priv->xdp_prog)
> + goto out;
> +
> + if (!xdp_mtu_valid(priv, new_mtu))
> + return -EINVAL;

An error message would be helpful to let the user know which MTU values are 
acceptable in XDP context.


RE: [PATCH net-next 1/8] dpaa2-eth: Add basic XDP support

2018-11-25 Thread Ioana Ciocoi Radulescu
> -Original Message-
> From: David Ahern 
> Sent: Saturday, November 24, 2018 11:49 PM
> To: Ioana Ciocoi Radulescu ;
> netdev@vger.kernel.org; da...@davemloft.net
> Cc: Ioana Ciornei 
> Subject: Re: [PATCH net-next 1/8] dpaa2-eth: Add basic XDP support
> 
> On 11/23/18 9:56 AM, Ioana Ciocoi Radulescu wrote:
> > @@ -215,6 +255,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv
> *priv,
> > struct dpaa2_fas *fas;
> > void *buf_data;
> > u32 status = 0;
> > +   u32 xdp_act;
> >
> > /* Tracing point */
> > trace_dpaa2_rx_fd(priv->net_dev, fd);
> > @@ -231,8 +272,14 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv
> *priv,
> > percpu_extras = this_cpu_ptr(priv->percpu_extras);
> >
> > if (fd_format == dpaa2_fd_single) {
> > +   xdp_act = run_xdp(priv, ch, (struct dpaa2_fd *)fd, vaddr);
> > +   if (xdp_act != XDP_PASS)
> > +   return;
> 
> please bump the rx counters (packets and bytes) regardless of what XDP
> outcome is.
> 
> Same for Tx; packets and bytes counter should be bumped for packets
> redirected by XDP.

Thanks for the feedback, I wasn't sure whether I should count them
as regular packets or not. I'll make the change in v2.

Ioana



Re: [PATCH net-next 1/8] dpaa2-eth: Add basic XDP support

2018-11-24 Thread David Ahern
On 11/23/18 9:56 AM, Ioana Ciocoi Radulescu wrote:
> @@ -215,6 +255,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
>   struct dpaa2_fas *fas;
>   void *buf_data;
>   u32 status = 0;
> + u32 xdp_act;
>  
>   /* Tracing point */
>   trace_dpaa2_rx_fd(priv->net_dev, fd);
> @@ -231,8 +272,14 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
>   percpu_extras = this_cpu_ptr(priv->percpu_extras);
>  
>   if (fd_format == dpaa2_fd_single) {
> + xdp_act = run_xdp(priv, ch, (struct dpaa2_fd *)fd, vaddr);
> + if (xdp_act != XDP_PASS)
> + return;

please bump the rx counters (packets and bytes) regardless of what XDP
outcome is.

Same for Tx; packets and bytes counter should be bumped for packets
redirected by XDP.





[PATCH net-next 1/8] dpaa2-eth: Add basic XDP support

2018-11-23 Thread Ioana Ciocoi Radulescu
We keep one XDP program reference per channel. The only actions
supported for now are XDP_DROP and XDP_PASS.

Until now we didn't enforce a maximum size for Rx frames based
on MTU value. Change that, since for XDP mode we must ensure no
scatter-gather frames can be received.

Signed-off-by: Ioana Radulescu 
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 182 ++-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h |   6 +
 2 files changed, 187 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 640967a..5340ac9 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -13,7 +13,8 @@
 #include 
 #include 
 #include 
-
+#include 
+#include 
 #include 
 
 #include "dpaa2-eth.h"
@@ -199,6 +200,45 @@ static struct sk_buff *build_frag_skb(struct 
dpaa2_eth_priv *priv,
return skb;
 }
 
+static u32 run_xdp(struct dpaa2_eth_priv *priv,
+  struct dpaa2_eth_channel *ch,
+  struct dpaa2_fd *fd, void *vaddr)
+{
+   struct bpf_prog *xdp_prog;
+   struct xdp_buff xdp;
+   u32 xdp_act = XDP_PASS;
+
+   rcu_read_lock();
+
+   xdp_prog = READ_ONCE(ch->xdp.prog);
+   if (!xdp_prog)
+   goto out;
+
+   xdp.data = vaddr + dpaa2_fd_get_offset(fd);
+   xdp.data_end = xdp.data + dpaa2_fd_get_len(fd);
+   xdp.data_hard_start = xdp.data;
+   xdp_set_data_meta_invalid();
+
+   xdp_act = bpf_prog_run_xdp(xdp_prog, );
+
+   switch (xdp_act) {
+   case XDP_PASS:
+   break;
+   default:
+   bpf_warn_invalid_xdp_action(xdp_act);
+   case XDP_ABORTED:
+   trace_xdp_exception(priv->net_dev, xdp_prog, xdp_act);
+   case XDP_DROP:
+   ch->buf_count--;
+   free_rx_fd(priv, fd, vaddr);
+   break;
+   }
+
+out:
+   rcu_read_unlock();
+   return xdp_act;
+}
+
 /* Main Rx frame processing routine */
 static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
 struct dpaa2_eth_channel *ch,
@@ -215,6 +255,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
struct dpaa2_fas *fas;
void *buf_data;
u32 status = 0;
+   u32 xdp_act;
 
/* Tracing point */
trace_dpaa2_rx_fd(priv->net_dev, fd);
@@ -231,8 +272,14 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv,
percpu_extras = this_cpu_ptr(priv->percpu_extras);
 
if (fd_format == dpaa2_fd_single) {
+   xdp_act = run_xdp(priv, ch, (struct dpaa2_fd *)fd, vaddr);
+   if (xdp_act != XDP_PASS)
+   return;
+
skb = build_linear_skb(ch, fd, vaddr);
} else if (fd_format == dpaa2_fd_sg) {
+   WARN_ON(priv->xdp_prog);
+
skb = build_frag_skb(priv, ch, buf_data);
skb_free_frag(vaddr);
percpu_extras->rx_sg_frames++;
@@ -1427,6 +1474,137 @@ static int dpaa2_eth_ioctl(struct net_device *dev, 
struct ifreq *rq, int cmd)
return -EINVAL;
 }
 
+static bool xdp_mtu_valid(struct dpaa2_eth_priv *priv, int mtu)
+{
+   int mfl, linear_mfl;
+
+   mfl = DPAA2_ETH_L2_MAX_FRM(mtu);
+   linear_mfl = DPAA2_ETH_RX_BUF_SIZE - DPAA2_ETH_RX_HWA_SIZE -
+dpaa2_eth_rx_head_room(priv);
+
+   return (mfl <= linear_mfl);
+}
+
+static int set_rx_mfl(struct dpaa2_eth_priv *priv, int mtu, bool has_xdp)
+{
+   int mfl, err;
+
+   /* We enforce a maximum Rx frame length based on MTU only if we have
+* an XDP program attached (in order to avoid Rx S/G frames).
+* Otherwise, we accept all incoming frames as long as they are not
+* larger than maximum size supported in hardware
+*/
+   if (has_xdp)
+   mfl = DPAA2_ETH_L2_MAX_FRM(mtu);
+   else
+   mfl = DPAA2_ETH_MFL;
+
+   err = dpni_set_max_frame_length(priv->mc_io, 0, priv->mc_token, mfl);
+   if (err) {
+   netdev_err(priv->net_dev, "dpni_set_max_frame_length failed\n");
+   return err;
+   }
+
+   return 0;
+}
+
+static int dpaa2_eth_change_mtu(struct net_device *dev, int new_mtu)
+{
+   struct dpaa2_eth_priv *priv = netdev_priv(dev);
+   int err;
+
+   if (!priv->xdp_prog)
+   goto out;
+
+   if (!xdp_mtu_valid(priv, new_mtu))
+   return -EINVAL;
+
+   err = set_rx_mfl(priv, new_mtu, true);
+   if (err)
+   return err;
+
+out:
+   dev->mtu = new_mtu;
+   return 0;
+}
+
+static int setup_xdp(struct net_device *dev, struct bpf_prog *prog)
+{
+   struct dpaa2_eth_priv *priv = netdev_priv(dev);
+   struct dpaa2_eth_channel *ch;
+   struct bpf_prog *old;
+   bool up, update_settings;
+   int i, err;
+
+   if (prog && !xdp_mtu_valid(priv, dev->mtu)) {
+