On 2018/09/10 17:24, Ilias Apalodimas wrote: > Add basic AF_XDP support without zero-copy > > Signed-off-by: Ilias Apalodimas <ilias.apalodi...@linaro.org> > --- ... > @@ -707,6 +731,26 @@ static int netsec_process_rx(struct netsec_priv *priv, > int budget) > if (unlikely(!buf_addr)) > break; > > + if (xdp_prog) { > + xdp_result = netsec_run_xdp(desc, priv, xdp_prog, > + pkt_len); > + if (xdp_result != NETSEC_XDP_PASS) { > + xdp_flush |= xdp_result & NETSEC_XDP_REDIR; > + > + dma_unmap_single_attrs(priv->dev, > + desc->dma_addr, > + desc->len, DMA_TO_DEVICE, > + DMA_ATTR_SKIP_CPU_SYNC); > + > + desc->len = desc_len; > + desc->dma_addr = dma_handle; > + desc->addr = buf_addr; > + netsec_rx_fill(priv, idx, 1); > + nsetsec_adv_desc(&dring->tail); > + } > + continue;
Continue even on XDP_PASS? Is this really correct? Also seems there is no handling of adjust_head/tail for XDP_PASS case. > + } > + > skb = build_skb(desc->addr, desc->len); > if (unlikely(!skb)) { > dma_unmap_single(priv->dev, dma_handle, desc_len, > @@ -740,6 +784,9 @@ static int netsec_process_rx(struct netsec_priv *priv, > int budget) > nsetsec_adv_desc(&dring->tail); > } > > + if (xdp_flush & NETSEC_XDP_REDIR) > + xdp_do_flush_map(); > + > return done; > } ... > +static u32 netsec_run_xdp(struct netsec_desc *desc, struct netsec_priv *priv, > + struct bpf_prog *prog, u16 len) > + > +{ > + struct netsec_desc_ring *dring = &priv->desc_ring[NETSEC_RING_RX]; > + struct xdp_buff xdp; > + u32 ret = NETSEC_XDP_PASS; > + int err; > + u32 act; > + > + xdp.data_hard_start = desc->addr; > + xdp.data = desc->addr; There is no headroom. REDIRECT using devmap/cpumap will fail due to this. Generally we need XDP_PACKET_HEADROOM. > + xdp_set_data_meta_invalid(&xdp); > + xdp.data_end = xdp.data + len; > + xdp.rxq = &dring->xdp_rxq; > + > + rcu_read_lock(); > + act = bpf_prog_run_xdp(prog, &xdp); > + > + switch (act) { > + case XDP_PASS: > + ret = NETSEC_XDP_PASS; > + break; > + case XDP_TX: > + ret = netsec_xmit_xdp(priv, &xdp, desc); > + break; > + case XDP_REDIRECT: > + err = xdp_do_redirect(priv->ndev, &xdp, prog); > + if (!err) { > + ret = NETSEC_XDP_REDIR; > + } else { > + ret = NETSEC_XDP_CONSUMED; > + xdp_return_buff(&xdp); > + } > + break; > + default: > + bpf_warn_invalid_xdp_action(act); > + /* fall through */ > + case XDP_ABORTED: > + trace_xdp_exception(priv->ndev, prog, act); > + /* fall through -- handle aborts by dropping packet */ > + case XDP_DROP: > + ret = NETSEC_XDP_CONSUMED; > + break; > + } > + > + rcu_read_unlock(); > + > + return ret; > +} > + > +static int netsec_xdp_setup(struct netsec_priv *priv, struct bpf_prog *prog) > +{ > + 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) { > + netdev_warn(dev, "Jumbo frames not yet supported with XDP\n"); Why not using extack? > + return -EOPNOTSUPP; > + } > + -- Toshiaki Makita