Re: [PATCH net-next 3/3] virtio-net: support XDP_REDIRECT
On 2017年09月21日 06:02, John Fastabend wrote: On 09/19/2017 02:42 AM, Jason Wang wrote: This patch tries to add XDP_REDIRECT for virtio-net. The changes are not complex as we could use exist XDP_TX helpers for most of the work. The rest is passing the XDP_TX to NAPI handler for implementing batching. Cc: John FastabendSigned-off-by: Jason Wang --- [...] @@ -678,12 +711,20 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, } break; case XDP_TX: - if (unlikely(!virtnet_xdp_xmit(vi, ))) + if (unlikely(!__virtnet_xdp_xmit(vi, ))) trace_xdp_exception(vi->dev, xdp_prog, act); + else + *xdp_xmit = true; if (unlikely(xdp_page != page)) goto err_xdp; rcu_read_unlock(); goto xdp_xmit; + case XDP_REDIRECT: + err = xdp_do_redirect(dev, , xdp_prog); + if (err) + *xdp_xmit = true; Is this a typo? Should above be if (!err) *xdp_xmit = true; this would match the pattern in receive_small and also make more sense. Right, will post a fix. + rcu_read_unlock(); + goto xdp_xmit; default: bpf_warn_invalid_xdp_action(act); case XDP_ABORTED: @@ -788,7 +829,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, } [...] Otherwise looks good to me thanks for doing this. .John Thanks for the reviewing.
Re: [PATCH net-next 3/3] virtio-net: support XDP_REDIRECT
On 2017年09月21日 06:02, John Fastabend wrote: On 09/19/2017 02:42 AM, Jason Wang wrote: This patch tries to add XDP_REDIRECT for virtio-net. The changes are not complex as we could use exist XDP_TX helpers for most of the work. The rest is passing the XDP_TX to NAPI handler for implementing batching. Cc: John Fastabend Signed-off-by: Jason Wang --- [...] @@ -678,12 +711,20 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, } break; case XDP_TX: - if (unlikely(!virtnet_xdp_xmit(vi, ))) + if (unlikely(!__virtnet_xdp_xmit(vi, ))) trace_xdp_exception(vi->dev, xdp_prog, act); + else + *xdp_xmit = true; if (unlikely(xdp_page != page)) goto err_xdp; rcu_read_unlock(); goto xdp_xmit; + case XDP_REDIRECT: + err = xdp_do_redirect(dev, , xdp_prog); + if (err) + *xdp_xmit = true; Is this a typo? Should above be if (!err) *xdp_xmit = true; this would match the pattern in receive_small and also make more sense. Right, will post a fix. + rcu_read_unlock(); + goto xdp_xmit; default: bpf_warn_invalid_xdp_action(act); case XDP_ABORTED: @@ -788,7 +829,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, } [...] Otherwise looks good to me thanks for doing this. .John Thanks for the reviewing.
Re: [PATCH net-next 3/3] virtio-net: support XDP_REDIRECT
On 09/19/2017 02:42 AM, Jason Wang wrote: > This patch tries to add XDP_REDIRECT for virtio-net. The changes are > not complex as we could use exist XDP_TX helpers for most of the > work. The rest is passing the XDP_TX to NAPI handler for implementing > batching. > > Cc: John Fastabend> Signed-off-by: Jason Wang > --- [...] > @@ -678,12 +711,20 @@ static struct sk_buff *receive_mergeable(struct > net_device *dev, > } > break; > case XDP_TX: > - if (unlikely(!virtnet_xdp_xmit(vi, ))) > + if (unlikely(!__virtnet_xdp_xmit(vi, ))) > trace_xdp_exception(vi->dev, xdp_prog, act); > + else > + *xdp_xmit = true; > if (unlikely(xdp_page != page)) > goto err_xdp; > rcu_read_unlock(); > goto xdp_xmit; > + case XDP_REDIRECT: > + err = xdp_do_redirect(dev, , xdp_prog); > + if (err) > + *xdp_xmit = true; Is this a typo? Should above be if (!err) *xdp_xmit = true; this would match the pattern in receive_small and also make more sense. > + rcu_read_unlock(); > + goto xdp_xmit; > default: > bpf_warn_invalid_xdp_action(act); > case XDP_ABORTED: > @@ -788,7 +829,7 @@ static struct sk_buff *receive_mergeable(struct > net_device *dev, > } > [...] Otherwise looks good to me thanks for doing this. .John
Re: [PATCH net-next 3/3] virtio-net: support XDP_REDIRECT
On 09/19/2017 02:42 AM, Jason Wang wrote: > This patch tries to add XDP_REDIRECT for virtio-net. The changes are > not complex as we could use exist XDP_TX helpers for most of the > work. The rest is passing the XDP_TX to NAPI handler for implementing > batching. > > Cc: John Fastabend > Signed-off-by: Jason Wang > --- [...] > @@ -678,12 +711,20 @@ static struct sk_buff *receive_mergeable(struct > net_device *dev, > } > break; > case XDP_TX: > - if (unlikely(!virtnet_xdp_xmit(vi, ))) > + if (unlikely(!__virtnet_xdp_xmit(vi, ))) > trace_xdp_exception(vi->dev, xdp_prog, act); > + else > + *xdp_xmit = true; > if (unlikely(xdp_page != page)) > goto err_xdp; > rcu_read_unlock(); > goto xdp_xmit; > + case XDP_REDIRECT: > + err = xdp_do_redirect(dev, , xdp_prog); > + if (err) > + *xdp_xmit = true; Is this a typo? Should above be if (!err) *xdp_xmit = true; this would match the pattern in receive_small and also make more sense. > + rcu_read_unlock(); > + goto xdp_xmit; > default: > bpf_warn_invalid_xdp_action(act); > case XDP_ABORTED: > @@ -788,7 +829,7 @@ static struct sk_buff *receive_mergeable(struct > net_device *dev, > } > [...] Otherwise looks good to me thanks for doing this. .John
Re: [PATCH net-next 3/3] virtio-net: support XDP_REDIRECT
From: Jason WangDate: Tue, 19 Sep 2017 17:42:43 +0800 > This patch tries to add XDP_REDIRECT for virtio-net. The changes are > not complex as we could use exist XDP_TX helpers for most of the > work. The rest is passing the XDP_TX to NAPI handler for implementing > batching. > > Cc: John Fastabend > Signed-off-by: Jason Wang Applied.
Re: [PATCH net-next 3/3] virtio-net: support XDP_REDIRECT
From: Jason Wang Date: Tue, 19 Sep 2017 17:42:43 +0800 > This patch tries to add XDP_REDIRECT for virtio-net. The changes are > not complex as we could use exist XDP_TX helpers for most of the > work. The rest is passing the XDP_TX to NAPI handler for implementing > batching. > > Cc: John Fastabend > Signed-off-by: Jason Wang Applied.
[PATCH net-next 3/3] virtio-net: support XDP_REDIRECT
This patch tries to add XDP_REDIRECT for virtio-net. The changes are not complex as we could use exist XDP_TX helpers for most of the work. The rest is passing the XDP_TX to NAPI handler for implementing batching. Cc: John FastabendSigned-off-by: Jason Wang --- drivers/net/virtio_net. | 0 drivers/net/virtio_net.c | 77 ++-- 2 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 drivers/net/virtio_net. diff --git a/drivers/net/virtio_net. b/drivers/net/virtio_net. new file mode 100644 index 000..e69de29 diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index db5924c..f6c1f13 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -29,6 +29,7 @@ #include #include #include +#include #include static int napi_weight = NAPI_POLL_WEIGHT; @@ -372,8 +373,20 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, return skb; } -static bool virtnet_xdp_xmit(struct virtnet_info *vi, -struct xdp_buff *xdp) +static void virtnet_xdp_flush(struct net_device *dev) +{ + struct virtnet_info *vi = netdev_priv(dev); + struct send_queue *sq; + unsigned int qp; + + qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id(); + sq = >sq[qp]; + + virtqueue_kick(sq->vq); +} + +static bool __virtnet_xdp_xmit(struct virtnet_info *vi, + struct xdp_buff *xdp) { struct virtio_net_hdr_mrg_rxbuf *hdr; unsigned int len; @@ -407,10 +420,19 @@ static bool virtnet_xdp_xmit(struct virtnet_info *vi, return false; } - virtqueue_kick(sq->vq); return true; } +static int virtnet_xdp_xmit(struct net_device *dev, struct xdp_buff *xdp) +{ + struct virtnet_info *vi = netdev_priv(dev); + bool sent = __virtnet_xdp_xmit(vi, xdp); + + if (!sent) + return -ENOSPC; + return 0; +} + static unsigned int virtnet_get_headroom(struct virtnet_info *vi) { return vi->xdp_queue_pairs ? VIRTIO_XDP_HEADROOM : 0; @@ -483,7 +505,8 @@ static struct sk_buff *receive_small(struct net_device *dev, struct virtnet_info *vi, struct receive_queue *rq, void *buf, void *ctx, -unsigned int len) +unsigned int len, +bool *xdp_xmit) { struct sk_buff *skb; struct bpf_prog *xdp_prog; @@ -493,7 +516,7 @@ static struct sk_buff *receive_small(struct net_device *dev, unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); struct page *page = virt_to_head_page(buf); - unsigned int delta = 0; + unsigned int delta = 0, err; struct page *xdp_page; len -= vi->hdr_len; @@ -541,8 +564,16 @@ static struct sk_buff *receive_small(struct net_device *dev, delta = orig_data - xdp.data; break; case XDP_TX: - if (unlikely(!virtnet_xdp_xmit(vi, ))) + if (unlikely(!__virtnet_xdp_xmit(vi, ))) trace_xdp_exception(vi->dev, xdp_prog, act); + else + *xdp_xmit = true; + rcu_read_unlock(); + goto xdp_xmit; + case XDP_REDIRECT: + err = xdp_do_redirect(dev, , xdp_prog); + if (!err) + *xdp_xmit = true; rcu_read_unlock(); goto xdp_xmit; default: @@ -603,7 +634,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, struct receive_queue *rq, void *buf, void *ctx, -unsigned int len) +unsigned int len, +bool *xdp_xmit) { struct virtio_net_hdr_mrg_rxbuf *hdr = buf; u16 num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers); @@ -613,6 +645,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, struct bpf_prog *xdp_prog; unsigned int truesize; unsigned int headroom = mergeable_ctx_to_headroom(ctx); + int err; head_skb = NULL; @@ -678,12 +711,20 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, } break; case XDP_TX: - if (unlikely(!virtnet_xdp_xmit(vi, ))) +
[PATCH net-next 3/3] virtio-net: support XDP_REDIRECT
This patch tries to add XDP_REDIRECT for virtio-net. The changes are not complex as we could use exist XDP_TX helpers for most of the work. The rest is passing the XDP_TX to NAPI handler for implementing batching. Cc: John Fastabend Signed-off-by: Jason Wang --- drivers/net/virtio_net. | 0 drivers/net/virtio_net.c | 77 ++-- 2 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 drivers/net/virtio_net. diff --git a/drivers/net/virtio_net. b/drivers/net/virtio_net. new file mode 100644 index 000..e69de29 diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index db5924c..f6c1f13 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -29,6 +29,7 @@ #include #include #include +#include #include static int napi_weight = NAPI_POLL_WEIGHT; @@ -372,8 +373,20 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, return skb; } -static bool virtnet_xdp_xmit(struct virtnet_info *vi, -struct xdp_buff *xdp) +static void virtnet_xdp_flush(struct net_device *dev) +{ + struct virtnet_info *vi = netdev_priv(dev); + struct send_queue *sq; + unsigned int qp; + + qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id(); + sq = >sq[qp]; + + virtqueue_kick(sq->vq); +} + +static bool __virtnet_xdp_xmit(struct virtnet_info *vi, + struct xdp_buff *xdp) { struct virtio_net_hdr_mrg_rxbuf *hdr; unsigned int len; @@ -407,10 +420,19 @@ static bool virtnet_xdp_xmit(struct virtnet_info *vi, return false; } - virtqueue_kick(sq->vq); return true; } +static int virtnet_xdp_xmit(struct net_device *dev, struct xdp_buff *xdp) +{ + struct virtnet_info *vi = netdev_priv(dev); + bool sent = __virtnet_xdp_xmit(vi, xdp); + + if (!sent) + return -ENOSPC; + return 0; +} + static unsigned int virtnet_get_headroom(struct virtnet_info *vi) { return vi->xdp_queue_pairs ? VIRTIO_XDP_HEADROOM : 0; @@ -483,7 +505,8 @@ static struct sk_buff *receive_small(struct net_device *dev, struct virtnet_info *vi, struct receive_queue *rq, void *buf, void *ctx, -unsigned int len) +unsigned int len, +bool *xdp_xmit) { struct sk_buff *skb; struct bpf_prog *xdp_prog; @@ -493,7 +516,7 @@ static struct sk_buff *receive_small(struct net_device *dev, unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); struct page *page = virt_to_head_page(buf); - unsigned int delta = 0; + unsigned int delta = 0, err; struct page *xdp_page; len -= vi->hdr_len; @@ -541,8 +564,16 @@ static struct sk_buff *receive_small(struct net_device *dev, delta = orig_data - xdp.data; break; case XDP_TX: - if (unlikely(!virtnet_xdp_xmit(vi, ))) + if (unlikely(!__virtnet_xdp_xmit(vi, ))) trace_xdp_exception(vi->dev, xdp_prog, act); + else + *xdp_xmit = true; + rcu_read_unlock(); + goto xdp_xmit; + case XDP_REDIRECT: + err = xdp_do_redirect(dev, , xdp_prog); + if (!err) + *xdp_xmit = true; rcu_read_unlock(); goto xdp_xmit; default: @@ -603,7 +634,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, struct receive_queue *rq, void *buf, void *ctx, -unsigned int len) +unsigned int len, +bool *xdp_xmit) { struct virtio_net_hdr_mrg_rxbuf *hdr = buf; u16 num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers); @@ -613,6 +645,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, struct bpf_prog *xdp_prog; unsigned int truesize; unsigned int headroom = mergeable_ctx_to_headroom(ctx); + int err; head_skb = NULL; @@ -678,12 +711,20 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, } break; case XDP_TX: - if (unlikely(!virtnet_xdp_xmit(vi, ))) + if